summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/context
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/doc/context')
-rw-r--r--Master/texmf-dist/doc/context/documents/general/leaflets/leaflet-mixing.pdfbin65347 -> 65629 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/magazines/mag-1105-mkiv.pdfbin0 -> 57255 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/cld-mkiv.pdfbin798293 -> 804291 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/evenmore.pdfbin1538298 -> 1624341 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-boxes.pdfbin75834 -> 78543 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-characters.pdfbin0 -> 52979 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-conditionals.pdfbin95412 -> 104674 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-grouping.pdfbin0 -> 30762 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-macros.pdfbin0 -> 87655 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-paragraphs.pdfbin0 -> 208745 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-scope.pdfbin0 -> 46060 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-security.pdfbin0 -> 41760 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/luametafun.pdfbin1697432 -> 5553137 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/luametatex.pdfbin1189457 -> 1385220 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/luatex.pdfbin1542992 -> 1544345 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/primitives.pdfbin0 -> 143288 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/units-mkiv.pdfbin164604 -> 113203 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-cs.pdfbin932229 -> 950852 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-de.pdfbin932682 -> 952439 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-en.pdfbin930546 -> 963860 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-fr.pdfbin930422 -> 961163 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-it.pdfbin934059 -> 958941 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-cs.pdfbin352043 -> 354602 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-de.pdfbin351418 -> 354810 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-en.pdfbin349070 -> 354208 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-fr.pdfbin351319 -> 357723 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-it.pdfbin350931 -> 355763 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-nl.pdfbin349696 -> 353260 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-ro.pdfbin552014 -> 564601 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-nl.pdfbin926927 -> 947389 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-ro.pdfbin930145 -> 949594 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-concepts.pdfbin0 -> 156486 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-concepts.tex694
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-datatypes.pdfbin0 -> 42978 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-datatypes.tex454
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-ecmascript.pdfbin0 -> 39008 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-ecmascript.tex272
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-gpdemo.gp8
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-gpdemo.svg157
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-implementers.pdfbin0 -> 39686 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-implementers.tex380
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-luametatex.pdfbin0 -> 40944 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-luametatex.tex529
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mkii-mkiv-mkxl.pdfbin0 -> 27908 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mkii-mkiv-mkxl.tex208
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mp.pdfbin0 -> 55930 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mp.tex342
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-sin.svg163
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-svg.pdfbin0 -> 33787 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-svg.tex123
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-tokens.pdfbin0 -> 45873 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2020/context-2020-tokens.tex287
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/ctxtools.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/pdftools.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/pstopdf.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/rlxtools.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texexec.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texmfstart.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/textools.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texutil.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/tmftools.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/xmltools.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/context.html8
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/context.man11
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/context.xml13
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/luatools.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-babel.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-base.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-bibtex.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-cache.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-chars.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-check.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-colors.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.html8
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.man11
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.xml13
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-dvi.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-epub.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-evohome.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-fcd.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-flac.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-fonts.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.html1
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.man5
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.xml1
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-metapost.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-modules.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-package.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-patterns.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-plain.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-profile.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-rsync.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-scite.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-server.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-texworks.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-tools.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-unicode.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-unzip.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-update.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-vscode.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-watch.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-youless.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtxrun.man2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/leaflets/leaflet-mixing.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/magazines/mag-1105-mkiv.tex194
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/about/about-titlepage.tex6
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-introduction.tex61
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-luafunctions.tex22
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-macros.tex6
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-mkiv.tex8
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-scanners.tex1048
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-specialcommands.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-variables.tex340
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-keywords.tex395
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-normalization.tex272
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-numbers.tex365
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-parameters.tex449
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-parsing.tex425
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-tokens.tex456
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore.tex18
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-compilation.tex71
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex711
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-style.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup.tex1
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/libraries/ecmascript-mkiv.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex25
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex18
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-characters.tex256
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-conditionals.tex182
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-expansion.tex40
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-grouping.tex170
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-macros.tex904
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex948
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-scope.tex341
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-security.tex254
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lua/lua-mkiv.tex8
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-arrow.tex6
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-color.tex138
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-introduction.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-poisson.tex159
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-technology.tex89
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun.tex6
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex189
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-codes.tex22
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex172
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex1025
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex166
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex140
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex386
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-lua.tex53
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex279
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex124
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-modifications.tex172
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex227
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-pdf.tex10
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-preamble.tex79
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex396
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-style.tex144
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex706
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex.tex132
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex23
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-fonts.tex21
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-lua.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-math.tex30
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-modifications.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-nodes.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex.tex9
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/mathml/envexamp.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/mcommon.tex8
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/gracht.mp1284
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-basics.tex309
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-debugging.tex237
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-effects.tex265
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment.tex46
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-examples.tex253
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-introduction.tex9
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-layout.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-lua.tex995
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-macros.tex13
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-reference.tex29
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex149
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-styles.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-text-lmtx.tex1519
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-text.tex125
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-welcome.tex64
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun.tex18
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-environment.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-memory.tex8
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-punk.tex3
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-tokenspeak.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-style.tex15
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/primitives/primitives.tex2378
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/publications/publications-titlepage.tex6
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/sql/sql-mkiv.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/swiglib/swiglib-mkiv.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/templates/templates-mkiv.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/tools/tools-mkiv.tex6
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/units/units-mkiv.tex40
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-mkiv.tex1
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-parallel.tex123
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-commands.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-expressions.tex1
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex4
210 files changed, 21978 insertions, 2669 deletions
diff --git a/Master/texmf-dist/doc/context/documents/general/leaflets/leaflet-mixing.pdf b/Master/texmf-dist/doc/context/documents/general/leaflets/leaflet-mixing.pdf
index a023f9e881e..f61de6d3f03 100644
--- a/Master/texmf-dist/doc/context/documents/general/leaflets/leaflet-mixing.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/leaflets/leaflet-mixing.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/magazines/mag-1105-mkiv.pdf b/Master/texmf-dist/doc/context/documents/general/magazines/mag-1105-mkiv.pdf
new file mode 100644
index 00000000000..71abf84ec2d
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/magazines/mag-1105-mkiv.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/cld-mkiv.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/cld-mkiv.pdf
index bac02979fe8..f0825379372 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/cld-mkiv.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/cld-mkiv.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/evenmore.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/evenmore.pdf
index 5c40721927c..73fe8115521 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/evenmore.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/evenmore.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-boxes.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-boxes.pdf
index 305e6bebab0..0ee0f66a16e 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-boxes.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-boxes.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-characters.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-characters.pdf
new file mode 100644
index 00000000000..e3e13063056
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-characters.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-conditionals.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-conditionals.pdf
index 5e3d82ceef7..6de0090b3d3 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-conditionals.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-conditionals.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-grouping.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-grouping.pdf
new file mode 100644
index 00000000000..a8d103236c8
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-grouping.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-macros.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-macros.pdf
new file mode 100644
index 00000000000..63689f1c82f
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-macros.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-paragraphs.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-paragraphs.pdf
new file mode 100644
index 00000000000..bde7fda146e
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-paragraphs.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-scope.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-scope.pdf
new file mode 100644
index 00000000000..0a17a314c1b
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-scope.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-security.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-security.pdf
new file mode 100644
index 00000000000..b92f00ce3c0
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-security.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/luametafun.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/luametafun.pdf
index fa15b985d87..25c37bdcb30 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/luametafun.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/luametafun.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/luametatex.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/luametatex.pdf
index fd83dfb5aa4..5c2e3aea1f2 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/luametatex.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/luametatex.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/luatex.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/luatex.pdf
index 553b1613dfc..eed48236a58 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/luatex.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/luatex.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/primitives.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/primitives.pdf
new file mode 100644
index 00000000000..9d6fe7670d3
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/primitives.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/units-mkiv.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/units-mkiv.pdf
index 5631be78e72..d4099121114 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/units-mkiv.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/units-mkiv.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-cs.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-cs.pdf
index 7c2f664f6ba..d209e6bfd09 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-cs.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-cs.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-de.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-de.pdf
index 09a121ef8a1..4d97df581d4 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-de.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-de.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-en.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-en.pdf
index a877fa0eafc..552b8f5eb86 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-en.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-en.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-fr.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-fr.pdf
index c5dfbf669cf..9812f4e2cee 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-fr.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-fr.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-it.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-it.pdf
index dcafda14a27..b9aafe70eb9 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-it.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-it.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-cs.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
index 8e2ac2e8415..a2f4fa91ea3 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-de.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-de.pdf
index f37ea8a163e..fafb7c17527 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-de.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-de.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-en.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-en.pdf
index 780de383410..505b8fcd26b 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-en.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-en.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-fr.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
index 2cb28142152..b04e5f50f04 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-it.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-it.pdf
index 75f5974833b..d383904838f 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-it.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-it.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-nl.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
index 039c02bd357..c8a6554476b 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-ro.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
index 4f49185b54f..0d21e5aa297 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-nl.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-nl.pdf
index e103267502f..336a7e35858 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-nl.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-nl.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-ro.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-ro.pdf
index 36f50680a19..bb09d153e7b 100644
--- a/Master/texmf-dist/doc/context/documents/general/qrcs/setup-ro.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-ro.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-concepts.pdf b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-concepts.pdf
new file mode 100644
index 00000000000..913db5ef32b
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-concepts.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-concepts.tex b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-concepts.tex
new file mode 100644
index 00000000000..a472a33f462
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-concepts.tex
@@ -0,0 +1,694 @@
+% language=us
+
+\usemodule[present-boring,abbreviations-logos]
+
+\startdocument
+ [title={CONCEPTS},
+ banner={experiments turned features},
+ location={context\enspace {\bf 2020}\enspace meeting}]
+
+% see datatypes, hyphenation etc
+
+\starttitle[title=Experiments]
+
+There have been quite some experiments. Some results were rejected, some kept.
+Here are a few (that come to mind). This talk is a mix of summary, discussion and
+some demos.
+
+\stoptitle
+
+\starttitle[title=Math]
+
+There are a couple of additional features in the math engine. Most concern a bit
+more control over hard coded behavior, but some are sort of new:
+
+\startbuffer
+test $a = b \discretionary class 3 {$<$}{$>$}{$\neq$} c$ test
+\stopbuffer
+
+\typebuffer
+
+When there is enough room this will give
+
+\getbuffer
+
+When \type {\hsize} is limited we get:
+
+{\hsize 4mm \getbuffer}
+
+\page
+
+\enabletrackers[math.toysymbol]
+
+\definemathtoysymbol[Plus] [bin][+]
+\definemathtoysymbol[Minus][bin][-]
+\definemathtoysymbol[Equal][rel][=]
+
+\start
+
+\let\darkblue\darkyellow %\showmakeup[glue]
+
+$\dorecurse{199} {
+ x_{#1} \ifodd#1\relax\Plus\else\Minus\fi
+} x_{200} \Equal n$
+
+\dorecurse{10} {
+ test \discretionary
+ {\darkred hel $\sqrt{y}$ lo}
+ {\darkgreen good $\sqrt{z}$ bye}
+ {\darkblue wel $\sqrt{x}$ come} test
+}
+
+\dorecurse{10} {test #1
+ $x + 2x \discretionary class 2
+ {$+ \, \cdots $}
+ {$ \cdots \, +$}
+ {$+ \, \cdots \, +$} nx$ test
+}
+
+\stop
+
+\stoptitle
+
+\starttitle[title=More math]
+
+In traditional \TEX\ the last setting wins:
+
+\startbuffer
+\def\whatevera
+ {\Umathordrelspacing \textstyle=50mu
+ \Umathopenbinspacing\textstyle=50mu}
+
+\def\whateverb
+ {\Umathordrelspacing \textstyle=25mu
+ \Umathopenbinspacing\textstyle=25mu}
+
+$\whatevera a = (-2)$ \par
+$\whateverb a = (-2)$ \par
+$\whatevera a = (-2) \quad \whateverb a = (-2)$ \par
+\stopbuffer
+
+\typebuffer \startpacked \getbuffer \stoppacked
+
+\page
+
+In \LUAMETATEX\ we can freeze settings on the spot:
+
+\startbuffer
+\def\whatevera
+ {\frozen\Umathordrelspacing \textstyle=50mu
+ \frozen\Umathopenbinspacing\textstyle=50mu}
+
+\def\whateverb
+ {\frozen\Umathordrelspacing \textstyle=25mu
+ \frozen\Umathopenbinspacing\textstyle=25mu}
+
+$\whatevera a = (-2)$ \par
+$\whateverb a = (-2)$ \par
+$\whatevera a = (-2) \quad \whateverb a = (-2)$ \par
+\stopbuffer
+
+\typebuffer \startpacked \getbuffer \stoppacked
+
+\stoptitle
+
+\starttitle[title=Macros]
+
+Not storing arguments:
+
+\starttyping
+\def\foo#1#0#3{....}
+
+\foo{11}{22}{33}
+
+\foo #1#0#3->....
+#1<-11
+#2<-
+#3<-33
+\stoptyping
+
+Ignoring arguments:
+
+\starttyping
+\def\foo#1#-#2{#1#2}
+
+\foo{1}{2}{3}
+
+13
+\stoptyping
+
+\page
+
+Normal behaviour:
+
+\starttyping
+\def\foo#1#2#3{#1#2#3}
+
+\foo{1}{{2}}{3}
+
+\foo #1#2#3->#1#2#3
+#1<-1
+#2<-{2}
+#3<-3
+\stoptyping
+
+Special behaviour:
+
+\starttyping
+\def\foo#1#+#3{#1#2#3}
+
+\foo #1#2#3->#1#2#3
+#1<-1
+#2<-{{2}}
+#3<-3
+\stoptyping
+
+\page
+
+Optional tokens (we also show some \TEX-expansion-horror here):
+
+\starttyping
+\edef\a!space{\expandtoken \ignorecatcode \spaceasciicode}
+
+\normalexpanded {
+
+ \protected \def \noexpand \doifelseinset#1#2%
+ {\noexpand\ifhasxtoks{,\a!space#1,}{,#2,}%
+ \noexpand\expandafter\noexpand\firstoftwoarguments
+ \noexpand\else
+ \noexpand\expandafter\noexpand\secondoftwoarguments
+ \noexpand\fi}
+
+}
+\stoptyping
+
+or as tokens (\type{\showluatokens\doifelseinset}) on the next page:
+
+\page
+
+\starttyping
+591504 13 1 argument
+643771 13 2 argument
+595596 14 0 end match
+633535 120 48 if test ifhasxtoks
+643789 1 123 left brace
+643793 12 44 other char
+643741 9 32 ignore
+185919 5 1 parameter
+633495 12 44 other char
+ 57752 2 125 right brace
+167619 1 123 left brace
+643686 12 44 other char
+228803 5 2 parameter
+643434 12 44 other char
+643792 2 125 right brace
+643788 114 0 expand after expandafter
+643775 125 0 call firstoftwoarguments
+590609 120 3 if test else
+643628 114 0 expand after expandafter
+643754 125 0 call secondoftwoarguments
+643763 120 2 if test fi
+\stoptyping
+
+\page
+
+Cheating with arguments:
+
+\startbuffer
+\def\foo#1=#2,{(#1/#2)}
+
+\foo 1=2,\ignorearguments
+\foo 1=2\ignorearguments
+\foo 1\ignorearguments
+\foo \ignorearguments
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+As in:
+
+\startbuffer
+\def\foo#1=#2,{\ifarguments\or(#1)\or(#1/#2)\fi}
+
+\foo 1=2,\ignorearguments
+\foo 1=2\ignorearguments
+\foo 1\ignorearguments
+\foo \ignorearguments
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\stoptitle
+
+\starttitle[title=Hyphenation]
+
+Hyphenation at work:
+
+\startlinecorrection[line]
+\startcombination[distance=3cm,nx=6]
+ {\vtop{\hsize 2mm \strut NEDERLANDS\vskip.5\lineheight}} {\type{NEDERLANDS}}
+ {\vtop{\hsize 2mm \strut Nederlands\vskip.5\lineheight}} {\type{Nederlands}}
+ {\vtop{\hsize 2mm \strut nederlands\vskip.5\lineheight}} {\type{nederlands}}
+ {\vtop{\hsize 2mm \strut \CONTEXT \vskip.5\lineheight}} {\type{\CONTEXT }}
+ {\vtop{\hsize 2mm \strut text\-test\vskip.5\lineheight}} {\type{text\-test}}
+ {\vtop{\hsize 2mm \strut test-test \vskip.5\lineheight}} {\type{test-test }}
+\stopcombination
+\stoplinecorrection
+
+Controlling hyphenation:
+
+\startbuffer[1]
+\nohyphens NEDERLANDS {\dohyphens Nederlands} nederlands
+\stopbuffer
+
+\startbuffer[2]
+NEDERLANDS {\nohyphens Nederlands} nederlands
+\stopbuffer
+
+\typebuffer[1] and \typebuffer[2]
+
+\startlinecorrection[line]
+\startcombination[distance=4cm,nx=2]
+ {\small \small \vtop{\hsize 2mm \strut \nl \getbuffer[1]}} {}
+ {\small \small \vtop{\hsize 2mm \strut \nl \getbuffer[2]}} {}
+\stopcombination
+\stoplinecorrection
+
+\page
+
+There are several ways to implement this:
+
+\startitemize
+\startitem choose a language with no patterns:
+ \startitemize[packed]
+ \startitem it's quite efficient \stopitem
+ \startitem we loose language specifics \stopitem
+ \stopitemize
+\stopitem
+\startitem set the left and right hyphen min values high:
+ \startitemize[packed]
+ \startitem it works okay \stopitem
+ \startitem it is a hack \stopitem
+ \startitem we still enter the routine \stopitem
+ \stopitemize
+\stopitem
+\startitem block the mechanism:
+ \startitemize[packed]
+ \startitem it provides detailed control \stopitem
+ \startitem it is conceptually clean \stopitem
+ \stopitemize
+\stopitem
+\stopitemize
+
+The last method is what we use in \LMTX:
+
+\type {\dohyphens} : {\tttf \meaning\dohyphens}
+
+\type {\nohyphens} : {\tttf \meaning\nohyphens}
+
+\page
+
+For the moment we have this (it might evolve):
+
+\starttyping[style=\tt\small\small]
+\chardef \completehyphenationmodecode \numexpr
+ \normalhyphenationmodecode % \discretionary
+ + \automatichyphenationmodecode % -
+ + \explicithyphenationmodecode % \-
+ + \syllablehyphenationmodecode % pattern driven
+ + \uppercasehyphenationmodecode % replaces \uchyph
+ + \compoundhyphenationmodecode % replaces \compoundhyphenmode
+ % \strictstarthyphenationmodecode % replaces \hyphenationbounds (strict = original tex)
+ % \strictendhyphenationmodecode % replaces \hyphenationbounds (strict = original tex)
+ + \automaticpenaltyhyphenationmodecode % replaces \hyphenpenaltymode (otherwise use \exhyphenpenalty)
+ + \explicitpenaltyhyphenationmodecode % replaces \hyphenpenaltymode (otherwise use \exhyphenpenalty)
+ + \permitgluehyphenationmodecode % turn glue into kern in \discretionary
+ + \permitallhyphenationmodecode % okay, let's be even more tolerant
+ + \permitmathreplacehyphenationmodecode % and again we're more permissive
+\relax
+\stoptyping
+
+This replaces some \LUATEX\ mode variables and adds some more which is why we now use
+a bitset instead of multiple parameters.
+
+\page
+
+In addition we have more detailed discretionary control:
+
+\startbuffer
+nederlands\discretionary {!}{!}{!}nederlands
+nederlands\discretionary options 1 {!}{!}{!}nederlands
+nederlands\discretionary options 2 {!}{!}{!}nederlands
+nederlands\discretionary options 3 {!}{!}{!}nederlands
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[line]
+\startcombination[distance=4cm,nx=4]
+ {\vtop{\hsize 1mm \strut \nl nederlands\discretionary {!}{!}{!}nederlands}} {}
+ {\vtop{\hsize 1mm \strut \nl nederlands\discretionary options 1 {!}{!}{!}nederlands}} {}
+ {\vtop{\hsize 1mm \strut \nl nederlands\discretionary options 2 {!}{!}{!}nederlands}} {}
+ {\vtop{\hsize 1mm \strut \nl nederlands\discretionary options 3 {!}{!}{!}nederlands}} {}
+\stopcombination
+\stoplinecorrection
+
+At some point it will become \quote {frozen} functionality and that's when it gets
+documented (first we need to integrate and play a bit more with it in \CONTEXT).
+
+\stoptitle
+
+\starttitle[title=Local control]
+
+In \LUATEX\ we have experimental (kind of ugly) immediate assignments that can be
+used in expansions without blocking (resulting in tokens that is).
+
+But now we now have local control:
+
+\startbuffer
+\newcount\foocounter
+
+\def\foo
+ {\advance\foocounter\plusone
+ \the\foocounter}
+
+\edef\oof{(\foo)(\foo)(\foo)(\foo)}
+
+\meaning\oof
+\stopbuffer
+
+\typebuffer
+
+{\tttf \nohyphens \veryraggedright \getbuffer}
+
+\page
+
+Immediate expansion:
+
+\startbuffer
+\def\foo
+ {\beginlocalcontrol
+ \advance\foocounter\plusone
+ \endlocalcontrol
+ \the\foocounter}
+
+\edef\oof{(\foo)(\foo)(\foo)(\foo)}
+
+\meaning\oof
+\stopbuffer
+
+\typebuffer
+
+{\tttf \getbuffer}
+
+Hidden assignments:
+
+\startbuffer
+\scratchcounterone \beginlocalcontrol
+ \scratchcountertwo 100
+ \multiply \scratchcountertwo by 4
+\endlocalcontrol \scratchcountertwo
+\the\scratchcounterone
+\stopbuffer
+
+\typebuffer
+
+{\tttf \getbuffer}
+
+% \the \beginlocalcontrol
+% \scratchcountertwo 100
+% \multiply \scratchcountertwo by 4
+% \endlocalcontrol \scratchcountertwo
+
+\page
+
+Fancy expansion:
+
+\startbuffer
+\protected\def\foo
+ {\beginlocalcontrol
+ \advance\foocounter\plusone
+ \endlocalcontrol
+ \the\foocounter}
+
+\edef\oof{(\foo)(\foo)(\foo)(\foo)}
+\edef\ofo{(\expand\foo)(\expand\foo)(\expand\foo)(\expand\foo)}
+
+\meaning\oof \par \meaning\ofo
+\stopbuffer
+
+\typebuffer
+
+{\tttf \getbuffer}
+
+And a teaser:
+
+\starttyping
+\protected\def\widthofcontent#1{\beginlocalcontrol
+ \setbox\scratchbox\hbox{#1}\endlocalcontrol \wd\scratchbox}
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=Conditionals]
+
+We can get nicer code that this:
+
+\starttyping
+\ifdim\scratchdimen=10pt
+ \expandafter\one
+\else\ifnum\scratchcounter=20
+ \expandafter\expandafter\expandafter\two
+\else
+ \expandafter\expandafter\expandafter\three
+\fi\fi
+\stoptyping
+
+This becomes:
+
+\starttyping
+\ifdim\scratchdimen=10pt
+ \expandafter\one
+\orelse\ifnum\scratchcounter=20
+ \expandafter\two
+\else
+ \expandafter\three
+\fi
+\stoptyping
+
+\page
+
+There is a bunch of extra conditions like the generic:
+
+\startnarrower \type {\ifcondition} \stopnarrower
+
+some token testers like:
+
+\startnarrower \type {\iftok} and \type {\ifhas(x)tok(s)} \stopnarrower
+
+some specific for math:
+
+\startnarrower \type {\ifmathstyle} and \type {\ifmathparameter} \stopnarrower
+
+macro helpers:
+
+\startnarrower \type {\ifarguments}, \type {\ifboolean} and \type {\ifempty} \stopnarrower
+
+robust number and dimension interception:
+
+\startnarrower \type {\ifchknum}, \type {\ifchkdim}, \type {\ifcmpnum}, \type {\ifcmpdim)}, \type {\ifnumval} and \type {\ifdimval} \stopnarrower
+
+bonus checks:
+
+\startnarrower \type {\iffrozen}, \type {\ifprotected} and \type {\ifusercmd} \stopnarrower
+
+and the mentioned:
+
+\startnarrower \type {\orelse} and \type {\orunless} \stopnarrower
+
+\stoptitle
+
+\starttitle[title=Migration]
+
+\startbuffer
+h: \setbox0\hbox{box \footnote{h: box}}\setbox2\hbox{\box 0}\box2\par
+h: \setbox0\hbox{copy \footnote{h: copy}}\setbox2\hbox{\copy 0}\box2\par
+h: \setbox0\hbox{unbox \footnote{h: unhbox}}\setbox2\hbox{\unhbox 0}\box2\par
+h: \setbox0\hbox{uncopy \footnote{h: unhcopy}}\setbox2\hbox{\unhcopy0}\box2\par
+
+v: \setbox0\hbox{box \footnote{v: box}}\setbox2\vbox{\box 0}\box2\par
+v: \setbox0\hbox{copy \footnote{v: copy}}\setbox2\vbox{\copy 0}\box2\par
+v: \setbox0\hbox{unbox \footnote{v: unhbox}}\setbox2\vbox{\unhbox 0}\box2\par
+v: \setbox0\hbox{uncopy \footnote{v: unhcopy}}\setbox2\vbox{\unhcopy0}\box2\par
+
+\starttabulate[||]
+\NC tabulate \footnote{tabulate} \NC \NR
+\stoptabulate
+\stopbuffer
+
+\typebuffer[style={\tt\small}]
+
+\page
+
+\startpacked \getbuffer \stoppacked
+
+% \setbox0\hbox{test \footnote{test}} (\prelistbox0) (\postlistbox0)
+% \setprelistbox0\hbox{BEFORE} \setpostlistbox0\hbox{AFTER}
+% \box0
+
+% \setbox0\hbox{test \footnote{test}} (\prelistcopy0) (\postlistcopy0)
+% \setprelistbox0\hbox{BEFORE} \setpostlistbox0\hbox{AFTER}
+% \box0
+
+\stoptitle
+
+\starttitle[title=Normalizing lines]
+
+We can have predictable lines:
+
+\startbuffer
+ \hangindent3cm \hangafter 2 \leftskip1cm \rightskip1cm \input ward \par
+\stopbuffer
+
+\typebuffer
+
+Standard (but already with left skips):
+
+\start
+ \bitwiseflip \normalizelinemode -\indentskipmodecode
+ \bitwiseflip \normalizelinemode -\normalizelinemodecode
+ \showmakeup \relax \getbuffer
+\stop
+
+Normalized (enhanced, no shifts, indent skip):
+
+\start
+ \bitwiseflip \normalizelinemode \indentskipmodecode
+ \bitwiseflip \normalizelinemode \normalizelinemodecode
+ \showmakeup \relax \getbuffer
+\stop
+
+\page
+
+\startbuffer
+ \parshape 2 1cm 10cm 2cm 15cm \leftskip1cm \rightskip1cm \input ward \par
+\stopbuffer
+
+\typebuffer
+
+Standard:
+
+\start
+ \bitwiseflip \normalizelinemode -\indentskipmodecode
+ \bitwiseflip \normalizelinemode -\normalizelinemodecode
+ \showmakeup \relax \getbuffer
+\stop
+
+Normalized:
+
+\start
+ \bitwiseflip \normalizelinemode \indentskipmodecode
+ \bitwiseflip \normalizelinemode \normalizelinemodecode
+ \showmakeup \relax \getbuffer
+\stop
+
+% {\showmakeup \getbuffer}
+
+\stoptitle
+
+\starttitle[title=Freezing paragraph properties]
+
+\startbuffer
+\forgetparagraphfreezing \placefigure[left]{}{} {\bf Andrew Cuomo:} \input cuomo
+\stopbuffer
+
+\typebuffer[style=\tt\small] \start \switchtobodyfont[8pt] \getbuffer \par \stop
+
+\startbuffer
+\setparagraphfreezing \placefigure[left]{}{} {\bf Andrew Cuomo:} \input cuomo
+\stopbuffer
+
+\typebuffer[style=\tt\small] \start \switchtobodyfont[8pt] \getbuffer \par \stop
+
+\stoptitle
+
+\starttitle[title=Wrapping up paragraphs]
+
+\setparagraphfreezing
+
+We have \type {\wrapuppar} as new hook. An experimental mechanism has been build
+around it so that Wolfgang and I can freak out on this.
+
+\startbuffer
+\def\TestA{\registerparwrapper
+ {A}
+ {[\ignorespaces}
+ {\removeunwantedspaces]\showparwrapperstate{A}}}
+
+\def\TestB#1{\registerparwrapper
+ {B#1}
+ {(\ignorespaces}
+ {\removeunwantedspaces)\showparwrapperstate{B#1}}}
+
+\def\TestC{\registerparwrapper
+ {C}
+ {<\ignorespaces}
+ {\removeunwantedspaces>\showparwrapperstate{C}\forgetparwrapper}}
+
+\def\TestR{\registerparwrapperreverse
+ {R}
+ {<\ignorespaces}
+ {\removeunwantedspaces>\showparwrapperstate{R}}}
+\stopbuffer
+
+\typebuffer[style=\tt\small] \getbuffer
+
+\page
+
+Example 1:
+
+\startbuffer
+\TestA
+\dorecurse{3}
+ {1.#1 before \ruledvbox{\hsize2em\raggedcenter\TestB1 !\par} after\par}
+\dorecurse{3}
+ {2.#1 before \ruledvbox{\hsize3em\raggedcenter !\par} after\par}
+\dorecurse{3}
+ {3.#1 before \ruledvbox{\hsize4em\raggedcenter\TestB2 !} after\par}
+\forgetparwrapper
+\dorecurse{3}
+ {4.#1 before \ruledvbox{\hsize5em\raggedcenter\TestB3 !} after\par}
+\TestC
+\dorecurse{3}
+ {5.#1 before \ruledvbox{\hsize2em\raggedcenter\TestA !} after\par}
+\stopbuffer
+
+\typebuffer[style=\tt\small]
+
+\startcolumns \startpacked \getbuffer \stoppacked \stopcolumns
+
+\page
+
+Example 2:
+
+\startbuffer
+\TestA
+\dorecurse{3}{6.#1 before after\par} \blank
+\TestB4
+\dorecurse{3}{7.#1 before after\par} \blank
+\TestB5
+\TestR
+\dorecurse{3}{8.#1 before after\par} \blank
+\stopbuffer
+
+\typebuffer[style=\tt\small]
+
+\startcolumns \startpacked \getbuffer \stoppacked \stopcolumns
+
+\stoptitle
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-datatypes.pdf b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-datatypes.pdf
new file mode 100644
index 00000000000..906b1fe04d2
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-datatypes.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-datatypes.tex b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-datatypes.tex
new file mode 100644
index 00000000000..590cdbf93e8
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-datatypes.tex
@@ -0,0 +1,454 @@
+\usemodule[present-boring,abbreviations-logos]
+
+\startdocument
+ [title={DATATYPES},
+ banner={additional datatypes in lmtx},
+ location={context\enspace {\bf 2020}\enspace meeting}]
+
+\starttitle[title=Native \TEX\ datatypes: simple registers]
+
+\startbuffer
+integer: \count 123 = 456 \the\count123
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\startbuffer
+dimension: \dimen123 = 456pt \the\dimen123
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\startbuffer
+glue: \skip123 = 6pt plus 5pt minus 4pt\relax \the\skip123
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\startbuffer
+muglue: \muskip123 = 6mu plus 5mu minus 4mu\relax \the\muskip123
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\startbuffer
+attribute: \attribute123 = 456 \the\attribute123
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\blank[2*line]
+
+\starttyping
+\global \the \countdef \dimendef \skipdef \muskipdef \attributedef
+\advance \multiply \divide \numexpr \dimexpr \glueexpr \muexpr
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=Native \TEX\ datatypes: tokens]
+
+\startbuffer
+toks: \toks123 = {456} \the\toks123
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\blank[2*line]
+
+\starttyping
+\global \the \toksdef
+\toksapp \etoksapp \xtoksapp \gtoksapp
+\tokspre \etokspre \xtokspre \gtokspre
+\stoptyping
+
+\blank[2*line]
+
+(in retrospect: eetex)
+
+\stoptitle
+
+\starttitle[title=Native \TEX\ datatypes: boxes]
+
+\startbuffer
+box: \box123 = \hbox {456} (\the\wd123,\the\ht123,\the\dp123) \box123
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\blank[2*line]
+
+\starttyping
+\global \box \copy \unhbox \unvbox
+\hbox \vbox \vtop \hpack \vpack \tpack
+\wd \ht \dp \boxtotal
+\boxdirection \boxattr
+\boxorientation \boxxoffset \boxyoffset \boxxmove \boxymove
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=Native \TEX\ datatypes: macros]
+
+\startbuffer
+\def\onetwothree{346} \onetwothree
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\blank[2*line]
+
+\starttyping
+\global \protected \frozen
+\def \edef \edef \xdef
+\meaning
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=Native \LUA\ datatypes: numbers]
+
+\startbuffer
+\ctxlua{local n = 123 context(n)}\quad
+\ctxlua{local n = 123.456 context(n)}\quad
+\ctxlua{local n = 123.4E56 context(n)}\quad
+\ctxlua{local n = 0x123 context(n)}\quad
+\ctxlua{local n = 0x1.37fe4cd4b70b2p-1 context(n)}
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\blank[2*line]
+
+\starttyping
++ - * / // % ^ | ~ & << >> == ~= < > <= >= ( )
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=Native \LUA\ datatypes: strings]
+
+\startbuffer
+\ctxlua{local s = "abc" context(s)}\quad
+\ctxlua{local s = 'abc' context(s)}\quad
+\ctxlua{local s = [[abc]] context(s)}\quad
+\ctxlua{local s = [==[abc]==] context(s)}\quad
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\blank[2*line]
+
+\starttyping
+.. # == ~= < > <= >=
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=Native \LUA\ datatypes: booleans and nil]
+
+\startbuffer
+\ctxlua{local b = true context(b)}\quad
+\ctxlua{local b = false context(b)}\quad
+\ctxlua{local n = nil context(n)}\quad
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\blank[2*line]
+
+\starttyping
+== ~= and or not
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=Native \LUA\ datatypes: some more]
+
+\starttyping
+functions
+userdata (lpeg is userdata)
+coroutine
+\stoptyping
+
+\LUAMETATEX\ provides tokens and nodes as userdata and some libraries also
+use them (complex, decimal, pdf, etc).
+
+\stoptitle
+
+\starttitle[title=Both worlds combined]
+
+\startitemize[packed]
+\startitem There are only 64K registers (although we can extend that if needed). \stopitem
+\startitem Accessing registers at the \LUA\ end is not that efficient. \stopitem
+\startitem So we have now datatypes at the \LUA\ end with access at the \TEX\ end. \stopitem
+\startitem Their values can go beyond what \TEX\ registers provide. \stopitem
+\stopitemize
+
+\startbuffer
+\luacardinal bar 123
+\luainteger bar -456
+\luafloat bar 123.456E-3
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\the\luacardinal bar \quad
+\the\luainteger bar \quad
+\the\luafloat bar
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\page
+
+The usual \LUA\ semantics apply:
+
+\startbuffer
+\luacardinal bar 0x123
+\luainteger bar -0x456
+\luafloat bar 0x123.456p-3
+\stopbuffer
+
+\typebuffer \getbuffer
+
+So, now we get:
+
+\startbuffer
+\the\luacardinal bar \quad
+\the\luainteger bar \quad
+\the\luafloat bar
+\stopbuffer
+
+\getbuffer
+
+Equal signs are optional:
+
+\startbuffer
+\luainteger gnu= 123456 \luafloat gnu= 123.456e12
+\luainteger gnu = 123456 \luafloat gnu = 123.456e12
+\luainteger gnu =123456 \luafloat gnu =123.456e12
+\stopbuffer
+
+\typebuffer
+
+These commands can be uses for assignments as well as serialization. They use the
+\LUAMETATEX\ value function feature.
+
+\page
+
+Dimensions are serialized differently so that they can be used like this:
+
+\startbuffer
+\luadimen test 100pt \scratchdimen = .25 \luadimen test: \the\scratchdimen
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\page
+
+Assume that we have this:
+
+\startbuffer
+\luacardinal x = -123 \luafloat x = 123.123
+\luacardinal y = 456 \luafloat y = -456.456
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can then use the macro \type {\luaexpression} that takes an optional keyword:
+
+\startbuffer
+- : \luaexpression {n.x + 2*n.y}
+f : \luaexpression float {n.x + 2*n.y}
+i : \luaexpression integer {n.x + 2*n.y}
+c : \luaexpression cardinal {n.x + 2*n.y}
+b : \luaexpression boolean {n.x + 2*n.y}
+l : \luaexpression lua {n.x + 2*n.y}
+\stopbuffer
+
+\typebuffer
+
+The serialization can be different for these cases:
+
+\startlines
+\tt \getbuffer
+\stoplines
+
+Variables have their own namespace but get resolved across namespaces (f, i, c).
+
+\page
+
+Special tricks:
+
+\startbuffer
+\scratchdimen 123.456pt [\the\scratchdimen] [\the\nodimen\scratchdimen]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Does nothing, nor does:
+
+\startbuffer
+\nodimen\scratchdimen = 654.321pt
+\stopbuffer
+
+\typebuffer \getbuffer
+
+But:
+
+\starttabulate[|T|T|]
+\NC \type {\the\nodimen bp \scratchdimen} \NC \the\nodimen bp \scratchdimen \NC \NR
+\NC \type {\the\nodimen cc \scratchdimen} \NC \the\nodimen cc \scratchdimen \NC \NR
+\NC \type {\the\nodimen cm \scratchdimen} \NC \the\nodimen cm \scratchdimen \NC \NR
+\NC \type {\the\nodimen dd \scratchdimen} \NC \the\nodimen dd \scratchdimen \NC \NR
+\NC \type {\the\nodimen in \scratchdimen} \NC \the\nodimen in \scratchdimen \NC \NR
+\NC \type {\the\nodimen mm \scratchdimen} \NC \the\nodimen mm \scratchdimen \NC \NR
+\NC \type {\the\nodimen pt \scratchdimen} \NC \the\nodimen pt \scratchdimen \NC \NR
+\NC \type {\the\nodimen sp \scratchdimen} \NC \the\nodimen sp \scratchdimen \NC \NR
+\stoptabulate
+
+gives different units! In the coffee break it was decided to drop the \type {nc}
+and \type {nd} units in \LUAMETATEX\ when Arthur indicated that they never became
+a standard. Dropping the \type {true} variants also makes sense but we postponed
+dropping the \type {in} (inch).
+
+\stoptitle
+
+\starttitle[title=Arrays]
+
+Two dimensional arrays have names and a type:
+
+\startbuffer
+\newarray name integers type integer nx 2 ny 2
+\newarray name booleans type boolean nx 2 ny 2
+\newarray name floats type float nx 2 ny 2
+\newarray name dimensions type dimension nx 4
+\stopbuffer
+
+\typebuffer \getbuffer
+
+And a special accessor. Here we set values:
+
+\startbuffer
+\arrayvalue integers 1 2 4 \arrayvalue integers 2 1 8
+\arrayvalue booleans 1 2 true \arrayvalue booleans 2 1 true
+\arrayvalue floats 1 2 12.34 \arrayvalue floats 2 1 34.12
+\arrayvalue dimensions 1 12.34pt \arrayvalue dimensions 3 34.12pt
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\page
+
+Here we get values:
+
+\startbuffer
+[\the\arrayvalue integers 1 2]
+[\the\arrayvalue booleans 1 2]
+[\the\arrayvalue floats 1 2]
+[\the\arrayvalue dimensions 1 ]\crlf
+[\the\arrayvalue integers 2 1]
+[\the\arrayvalue booleans 2 1]
+[\the\arrayvalue floats 2 1]
+[\the\arrayvalue dimensions 3]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+When a value is expected the integer is serialized:
+
+\startbuffer
+\scratchcounter\arrayvalue integers 1 2\relax \the\scratchcounter
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+You can view an array on the console with:
+
+\starttyping
+\showarray integers
+\stoptyping
+
+\page
+
+Another expression example:
+
+\startbuffer
+\dostepwiserecurse {1} {4} {1} {
+ [\the\arrayvalue dimensions #1 :
+ \luaexpression dimen {math.sind(30) * a.dimensions[#1]}]
+}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\page
+
+We can combine it all with if tests:
+
+\startbuffer
+slot 1 is \ifboolean\arrayequals dimensions 1 0pt zero \else not zero \fi\quad
+slot 2 is \ifboolean\arrayequals dimensions 2 0pt zero \else not zero \fi
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\startbuffer
+slot 1: \ifcase\arraycompare dimensions 1 3pt lt \or eq \else gt \fi zero\quad
+slot 2: \ifcase\arraycompare dimensions 2 3pt lt \or eq \else gt \fi zero\quad
+slot 3: \ifcase\arraycompare dimensions 3 3pt lt \or eq \else gt \fi zero\quad
+slot 4: \ifcase\arraycompare dimensions 4 3pt lt \or eq \else gt \fi zero
+
+slot 1: \ifcmpdim\arrayvalue dimensions 1 3pt lt \or eq \else gt \fi zero\quad
+slot 2: \ifcmpdim\arrayvalue dimensions 2 3pt lt \or eq \else gt \fi zero\quad
+slot 3: \ifcmpdim\arrayvalue dimensions 3 3pt lt \or eq \else gt \fi zero\quad
+slot 4: \ifcmpdim\arrayvalue dimensions 4 3pt lt \or eq \else gt \fi zero
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\stoptitle
+
+\starttitle[title=Complex numbers]
+
+\startbuffer
+\startluacode
+local c1 = xcomplex.new(1,3)
+local c2 = xcomplex.new(2,4)
+context(c1) context.quad() context(c2) context.quad(c1 + c2)
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stoptitle
+
+\starttitle[title=Decimal numbers]
+
+\startbuffer
+\startluacode
+local c1 = xdecimal.new("123456789012345678901234567890")
+local c2 = xdecimal.new(1234567890)
+context(c1) context.crlf() context(c2) context.crlf(c1 * c2)
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stoptitle
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-ecmascript.pdf b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-ecmascript.pdf
new file mode 100644
index 00000000000..35764258c7b
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-ecmascript.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-ecmascript.tex b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-ecmascript.tex
new file mode 100644
index 00000000000..20877d63376
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-ecmascript.tex
@@ -0,0 +1,272 @@
+% language=us
+
+\usemodule[present-boring,abbreviations-logos]
+
+\startdocument
+ [title={ECMASCRIPT},
+ banner={just because it can be done},
+ location={context\enspace {\bf 2020}\enspace meeting}]
+
+\starttitle[title=Why oh why]
+
+\startitemize
+
+\startitem
+ We use a \type {mupdf} based \PDF\ viewer: \type {SumatraPDF}.
+\stopitem
+\startitem
+ And occasionally we use the tools that come with \type {mupdf}.
+\stopitem
+\startitem
+ So when checking if that viewer supports \JAVASCRIPT\ in widgets I noticed
+ the stand alone interpreter. \footnote {The official name is \ECMASCRIPT\
+ which is the standardized core language.}
+\stopitem
+\startitem
+ Which made me wonder how easy it would be to interface to it.
+\stopitem
+
+\blank
+
+\startitem
+ It uses the lightweight library subsystem: like \FFI\ the library interface
+ is setup dynamically.
+\stopitem
+\startitem
+ Support is {\em not} integrated in \LUAMETATEX, so there is no overhead and
+ there are no dependencies.
+\stopitem
+\startitem
+ We assume that the library is on the system, and when not, then there is also
+ also no support.
+\stopitem
+\startitem
+ We stick to the absolute minimum of interfacing needed and delegate
+ everything else to \LUA.
+\stopitem
+\startitem
+ We assume a stable \API, and if not, well \unknown\ sorry.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=The components]
+
+\startitemize
+
+\startitem
+ The optional, delayed loading, interface, adds only a few KB to \LUAMETATEX.
+\stopitem
+
+\startitem
+ The \LUA\ library interface that is part of the \CONTEXT\ distribution which means
+ that it's officially supported.
+\stopitem
+
+\startitem
+ There is a \TEX\ module that loads the lot and provides the user interface.
+\stopitem
+
+\startitem
+ And of course, somewhere on the system, there should be the \type {mujs}
+ library. \footnote {Taco compiled the library for his system during the talk
+ and confirmed that it also works out of the box on \OSX.}
+\stopitem
+
+\startitem
+ A module like this should conform to the \CONTEXT\ \LMTX\ standards (a
+ minimalistic not bloated \API, interfacing in \LUA\ and \TEX, etc.).
+\stopitem
+
+\stopitemize
+
+\blank[2*line]
+
+In \CONTEXT\ libraries go into the platform tree, like:
+
+\starttyping
+/tex/texmf-win64/bin/lib/luametatex/mujs/libmujs.dll
+/tex/texmf-linux-64/bin/lib/luametatex/mujs/libmujs.so
+/tex/texmf-osx-64/bin/lib/luametatex/mujs/libmujs.so
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=An example]
+
+\startbuffer
+\usemodule[ecmascript]
+
+\ecmacode {
+ console("");
+ console("When you see this, the loading has succeeded!");
+ console("");
+}
+
+\ecmacode {texprint("Just a {\\bf short} sentence.")}
+
+\startecmacode
+ texprint("And this is \\inframed{\\bs a bit longer} sentence.")
+\stopecmacode
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\stoptitle
+
+\starttitle[title=Catcodes]
+
+As with the \LUA\ interface, catcode regimes are supported:
+
+\startbuffer
+\ecmacode {texprint(catcodes.vrb,"Just a {\\bf short} sentence.")}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Possible values are:
+
+\starttabulate
+\NC \type {tex} \NC regular \TEX\ catcode regime \NC \NR
+\NC \type {ctx} \NC standard \CONTEXT\ catcode regime \NC \NR
+\NC \type {vrb} \NC verbatim catcode regime \NC \NR
+\NC \type {prt} \NC protected \CONTEXT\ catcode regime \NC \NR
+\stoptabulate
+
+\stoptitle
+
+\starttitle[title=Print whatever you want]
+
+\startbuffer
+\startecmacode
+ console("We're doing some MetaPost!");
+ texsprint(
+ "\\startMPcode "
+ + 'fill fullsquare xyscaled (6cm,1cm) withcolor "darkgray";'
+ + 'fill fullsquare xyscaled (4cm,1cm) withcolor "middlegray";'
+ + 'fill fullsquare xyscaled (2cm,1cm) withcolor "lightgray";'
+ + "\\stopMPcode "
+ );
+\stopecmacode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Of course the code doesn't look pretty but it can serve as a step|-|up to the real
+deal: coding in \CONTEXT\ speak (or \LUA).
+
+\stoptitle
+
+\starttitle[title=Files]
+
+Because the interpreter is pretty bare, interfacing to the file system has to be
+provided but we can just use what we already have (controlled by \LUA).
+
+\startbuffer
+\startecmacode
+ var f = File("\jobname","r");
+ var l = f.read("*a");
+ f.close();
+ texprint(
+ "This file has "
+ + l.length // or: l.length.toString()
+ + " bytes!"
+ )
+\stopecmacode
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We support the usual arguments, like \type {*a}, \type {*l}, a number indicating
+the bytes to read etc. There is no support for writing files (let's use the
+security excuse).
+
+\page
+
+A file with some script:
+
+\startluacode
+io.savedata("context-2020-ecmascript.js",[[
+function filesize(name) {
+ var f = File(name,"r");
+ if (f != undefined) {
+ var l = f.seek("end");
+ f.close();
+ return l;
+ } else {
+ return 0;
+ }
+}
+]])
+\stopluacode
+
+\typefile{context-2020-ecmascript.js}
+
+Loading that file:
+
+\startbuffer
+\ecmafile{context-2020-ecmascript.js}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Using that function:
+
+\startbuffer
+\ecmacode{texsprint("This file has " + filesize("\jobname.tex") + " bytes!")}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stoptitle
+
+\starttitle[title=Ecmascript from \LUA]
+
+\startbuffer
+\startluacode
+ optional.loaded.mujs.execute [[
+ var MyMax = 10; // an example of persistence
+ ]]
+
+ optional.loaded.mujs.execute [[
+ texsprint("\\startpacked");
+ for (var i = 1; i <= MyMax; i++) {
+ texprint(
+ "Here is some rather dumb math test: "
+ + Math.sqrt(i/MyMax)
+ + "!\\par"
+ );
+ }
+ texsprint("\\stoppacked");
+ ]]
+\stopluacode
+\stopbuffer
+
+\typebuffer \page The result: \getbuffer
+
+\stoptitle
+
+\starttitle[title=So what good is it]
+
+\startitemize
+\startitem Not that much value is added compared to what we already have. \stopitem
+\startitem But at least we can say that we can do \ECMASCRIPT\ (aka \JAVASCRIPT). \stopitem
+\startitem And it might convince (new) users to use the \LUA\ interfaces instead. \stopitem
+\startitem So we pay a low price and have no overhead anyway. \stopitem
+\stopitemize
+
+\stoptitle
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-gpdemo.gp b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-gpdemo.gp
new file mode 100644
index 00000000000..1f21ca57cf4
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-gpdemo.gp
@@ -0,0 +1,8 @@
+set format xy "$%g$"
+
+set title 'This is a plot of $y=\sin(x)$'
+set xlabel 'This is the $x$ axis'
+set ylabel 'This is the $y$ axis'
+
+plot [0:6.28] [0:1] sin(x)
+
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-gpdemo.svg b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-gpdemo.svg
new file mode 100644
index 00000000000..eb7d6de3c3a
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-gpdemo.svg
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="windows-1252" standalone="no"?>
+<svg
+ width="600" height="480"
+ viewBox="0 0 600 480"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+>
+
+<title>Gnuplot</title>
+<desc>Produced by GNUPLOT 5.5 patchlevel 0 </desc>
+
+<g id="gnuplot_canvas">
+
+<rect x="0" y="0" width="600" height="480" fill="none"/>
+<defs>
+
+ <circle id='gpDot' r='0.5' stroke-width='0.5' stroke='currentColor'/>
+ <path id='gpPt0' stroke-width='0.222' stroke='currentColor' d='M-1,0 h2 M0,-1 v2'/>
+ <path id='gpPt1' stroke-width='0.222' stroke='currentColor' d='M-1,-1 L1,1 M1,-1 L-1,1'/>
+ <path id='gpPt2' stroke-width='0.222' stroke='currentColor' d='M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1'/>
+ <rect id='gpPt3' stroke-width='0.222' stroke='currentColor' x='-1' y='-1' width='2' height='2'/>
+ <rect id='gpPt4' stroke-width='0.222' stroke='currentColor' fill='currentColor' x='-1' y='-1' width='2' height='2'/>
+ <circle id='gpPt5' stroke-width='0.222' stroke='currentColor' cx='0' cy='0' r='1'/>
+ <use xlink:href='#gpPt5' id='gpPt6' fill='currentColor' stroke='none'/>
+ <path id='gpPt7' stroke-width='0.222' stroke='currentColor' d='M0,-1.33 L-1.33,0.67 L1.33,0.67 z'/>
+ <use xlink:href='#gpPt7' id='gpPt8' fill='currentColor' stroke='none'/>
+ <use xlink:href='#gpPt7' id='gpPt9' stroke='currentColor' transform='rotate(180)'/>
+ <use xlink:href='#gpPt9' id='gpPt10' fill='currentColor' stroke='none'/>
+ <use xlink:href='#gpPt3' id='gpPt11' stroke='currentColor' transform='rotate(45)'/>
+ <use xlink:href='#gpPt11' id='gpPt12' fill='currentColor' stroke='none'/>
+ <path id='gpPt13' stroke-width='0.222' stroke='currentColor' d='M0,1.330 L1.265,0.411 L0.782,-1.067 L-0.782,-1.076 L-1.265,0.411 z'/>
+ <use xlink:href='#gpPt13' id='gpPt14' fill='currentColor' stroke='none'/>
+ <filter id='textbox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
+ <feFlood flood-color='white' flood-opacity='1' result='bgnd'/>
+ <feComposite in='SourceGraphic' in2='bgnd' operator='atop'/>
+ </filter>
+ <filter id='greybox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
+ <feFlood flood-color='lightgrey' flood-opacity='1' result='grey'/>
+ <feComposite in='SourceGraphic' in2='grey' operator='atop'/>
+ </filter>
+</defs>
+<g fill="none" color="white" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M80.2,422.4 L89.2,422.4 M575.0,422.4 L566.0,422.4 '/> <g transform="translate(71.9,426.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >$0$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M80.2,348.7 L89.2,348.7 M575.0,348.7 L566.0,348.7 '/> <g transform="translate(71.9,352.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >$0.2$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M80.2,275.1 L89.2,275.1 M575.0,275.1 L566.0,275.1 '/> <g transform="translate(71.9,279.0)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >$0.4$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M80.2,201.4 L89.2,201.4 M575.0,201.4 L566.0,201.4 '/> <g transform="translate(71.9,205.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >$0.6$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M80.2,127.8 L89.2,127.8 M575.0,127.8 L566.0,127.8 '/> <g transform="translate(71.9,131.7)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >$0.8$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M80.2,54.1 L89.2,54.1 M575.0,54.1 L566.0,54.1 '/> <g transform="translate(71.9,58.0)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >$1$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M80.2,422.4 L80.2,413.4 M80.2,54.1 L80.2,63.1 '/> <g transform="translate(80.2,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >$0$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M159.0,422.4 L159.0,413.4 M159.0,54.1 L159.0,63.1 '/> <g transform="translate(159.0,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >$1$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M237.8,422.4 L237.8,413.4 M237.8,54.1 L237.8,63.1 '/> <g transform="translate(237.8,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >$2$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M316.6,422.4 L316.6,413.4 M316.6,54.1 L316.6,63.1 '/> <g transform="translate(316.6,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >$3$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M395.4,422.4 L395.4,413.4 M395.4,54.1 L395.4,63.1 '/> <g transform="translate(395.4,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >$4$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M474.1,422.4 L474.1,413.4 M474.1,54.1 L474.1,63.1 '/> <g transform="translate(474.1,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >$5$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M552.9,422.4 L552.9,413.4 M552.9,54.1 L552.9,63.1 '/> <g transform="translate(552.9,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >$6$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M80.2,54.1 L80.2,422.4 L575.0,422.4 L575.0,54.1 L80.2,54.1 Z '/></g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <g transform="translate(19.0,238.3) rotate(270)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >This is the $y$ axis</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <g transform="translate(327.6,471.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >This is the $x$ axis</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <g transform="translate(327.6,31.0)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >This is a plot of $y=sin(x)$</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+ <g id="gnuplot_plot_1" ><title>sin(x)</title>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <g transform="translate(507.9,76.0)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text>sin(x)</text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='rgb(148, 0, 211)' d='M516.2,72.1 L558.4,72.1 M80.2,422.4 L85.2,399.1 L90.2,375.8 L95.2,352.7 L100.2,329.9 L105.2,307.5
+ L110.2,285.6 L115.2,264.2 L120.2,243.4 L125.2,223.4 L130.2,204.1 L135.2,185.8 L140.2,168.3 L145.2,152.0
+ L150.2,136.6 L155.2,122.5 L160.2,109.5 L165.2,97.9 L170.2,87.5 L175.2,78.4 L180.2,70.8 L185.2,64.5
+ L190.2,59.7 L195.2,56.4 L200.2,54.5 L205.1,54.1 L210.1,55.2 L215.1,57.8 L220.1,61.8 L225.1,67.3
+ L230.1,74.2 L235.1,82.6 L240.1,92.2 L245.1,103.2 L250.1,115.5 L255.1,129.1 L260.1,143.8 L265.1,159.6
+ L270.1,176.5 L275.1,194.4 L280.1,213.2 L285.1,232.8 L290.1,253.2 L295.1,274.3 L300.1,295.9 L305.1,318.1
+ L310.1,340.7 L315.1,363.7 L320.1,386.8 L325.1,410.1 L327.7,422.4 '/></g>
+ </g>
+<g fill="none" color="white" stroke="rgb(148, 0, 211)" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="black" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M80.2,54.1 L80.2,422.4 L575.0,422.4 L575.0,54.1 L80.2,54.1 Z '/></g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+</g>
+</svg>
+
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-implementers.pdf b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-implementers.pdf
new file mode 100644
index 00000000000..94c51513802
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-implementers.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-implementers.tex b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-implementers.tex
new file mode 100644
index 00000000000..e1104dabf53
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-implementers.tex
@@ -0,0 +1,380 @@
+% language=us
+
+% \enabletrackers[context*]
+
+\usemodule[present-boring,abbreviations-logos]
+
+\startdocument
+ [title={IMPLEMENTERS},
+ banner={an old feature still evolving},
+ location={context\enspace {\bf 2020}\enspace meeting}]
+
+\starttitle[title=Interfacing with \LUA]
+
+\startitemize
+
+\startitem
+ Quite some activity is delegated to \LUA.
+\stopitem
+\startitem
+ Normally the initiative is at the \TEX\ end.
+\stopitem
+\startitem
+ We can set variables or call functions etc.
+\stopitem
+\startitem
+ We can parameters to function calls.
+\stopitem
+\startitem
+ From the \LUA\ end we can use scanners to pick up data.
+\stopitem
+\startitem
+ We provide some consistent interfaces for doing all that.
+\stopitem
+\startitem
+ From \TEX\ to \LUA\ we use \type {\ctxlua{...}} and friends.
+\stopitem
+\startitem
+ From \LUA\ to \TEX\ we use \type {context(...)} and alike.
+\stopitem
+\startitem
+ For adding functionality we use so called implementers.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Calling \LUA]
+
+\startbuffer
+\ctxlua{context("ok")}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\ctxlua{context(2 * tokens.scanners.integer())} 10
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startluacode
+function document.MyThing() context(2 * tokens.scanners.integer()) end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\ctxlua{document.MyThing()} 20 \quad
+\ctxlua{document.MyThing()} 30 \quad
+\ctxlua{document.MyThing()} 40
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stoptitle
+
+\starttitle[title=Streamlining \LUA]
+
+\startbuffer
+\startluacode
+interfaces.implement {
+ name = "MyThing",
+ public = true,
+ arguments = "integer",
+ actions = function(i) context(i * 2) end,
+ -- actions = { function(i) return i * 2 end, context },
+}
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\MyThing 20 \quad \MyThing 30 \quad \MyThing 40
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stoptitle
+
+\starttitle[title=Making commands]
+
+\startbuffer
+\startluacode
+interfaces.implement {
+ name = "MyRoot",
+ public = true,
+ actions = function()
+ local a = tokens.scanners.integer()
+ if not tokens.scanners.keyword("of") then
+ -- tex.error("the keyword 'of' expected")
+ end
+ local b = tokens.scanners.integer()
+ context("%0.6N",math.sqrt(b,a))
+ end,
+}
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\MyRoot 2 of 40 \quad \MyRoot 3 60
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stoptitle
+
+\starttitle[title=Scanners]
+
+There are lots of scanners: \blank
+
+\startalign[flushleft,broad] \tttf
+ \cldcontext { table.concat ( table.sortedkeys (tokens.scanners), " " ) }
+\stopalign
+
+\stoptitle
+
+\starttitle[title=A more complex example]
+
+Let's implement a matcher: \blank
+
+\startbuffer
+\doloopovermatch {(.)} {luametatex} { [#1] }
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\doloopovermatch {([\letterpercent w]+)} {\cldloadfile{tufte.tex}} { [#1] }
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stoptitle
+
+\starttitle[title=A more complex example (\TEX)]
+
+Here is the macro definition of this loop: \blank
+
+\starttyping
+\protected\def\doloopovermatch#1#2#3%
+ {\pushmacro\matchloopcommand
+ \def\matchloopcommand##1##2##3##4##5##6##7##8##9{#3}%
+ \ctxluamatch\matchloopcommand{#1}{#2}%
+ \popmacro\matchloopcommand}
+\stoptyping
+
+\startitemize
+
+\startitem The pushing and popping makes it possible to nest this macro. \stopitem
+\startitem The definition of the internal match macro permits argument references. \stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=A more complex example (\LUA)]
+
+At the \LUA\ end we use an implementer: \blank
+
+\starttyping[style=\small\tt]
+local escape = function(s) return "\\" .. string.byte(s) end
+
+interfaces.implement {
+ name = "ctxluamatch",
+ public = true,
+ usage = "value",
+ actions = function()
+ local command = context[tokens.scanners.csname()]
+ local pattern = string.gsub(tokens.scanners.string(),"\\.",escape)
+ local input = string.gsub(tokens.scanners.string(),"\\.",escape)
+ for a, b, c, d, e, f, g, h, i in string.gmatch(input,pattern) do
+ command(a, b or "", c or "", d or "", e or "", f or "", g or "",
+ h or "", i or "")
+ end
+ return tokens.values.none
+ end,
+}
+\stoptyping
+
+So what does the \type {usage} key tells the implementer?
+
+\stoptitle
+
+\starttitle[title=Value functions]
+
+Normally we pipe back verbose strings that are interpreted as if they were
+files. Value functions are different;
+
+\startitemize
+
+\startitem
+ The return value indicates what gets fed back in the input.
+\stopitem
+\startitem
+ This can be: \cldcontext { table.concat(token.getfunctionvalues(), ", ", 0) }.
+\stopitem
+\startitem
+ When possible an efficient token is injected.
+\stopitem
+\startitem
+ Value function can check if they are supposed to feed back a value.
+\stopitem
+\startitem
+ So, they can be used as setters and getters.
+\stopitem
+\startitem
+ A variant is a function that is seen as conditional.
+\stopitem
+\startitem
+ In (simple) tracing they are presented as primitives.
+\stopitem
+\startitem
+ They are protected against user overload (aka: frozen).
+\stopitem
+\startitem
+ All this is experimental and might evolve.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=So, let's step up a level]
+
+Say that we want an expandable command:
+
+\startbuffer
+\edef\foo{\doloopovermatched{.}{123}{(#1)}} \meaning\foo
+\stopbuffer
+
+\typebuffer \blank \getbuffer \blank
+
+Or nested:
+
+\startbuffer
+\edef\foo {%
+ \doloopovermatched {(..)} {123456} {%
+ \doloopovermatched {(.)(.)} {#1} {%
+ [##1][##2]%
+ }%
+ }%
+} \meaning\foo
+\stopbuffer
+
+\typebuffer \blank \getbuffer \blank
+
+\stoptitle
+
+\starttitle[title=So, let's step up a level]
+
+Compare:
+
+\starttyping[style=\small\tt]
+\protected\def\doloopovermatch#1#2#3%
+ {\pushmacro\matchloopcommand
+ \def\matchloopcommand##1##2##3##4##5##6##7##8##9{#3}%
+ \ctxluamatch\matchloopcommand{#1}{#2}%
+ \popmacro\matchloopcommand}
+\stoptyping
+
+With:
+
+\starttyping[style=\small\tt]
+\def\doloopovermatched#1#2#3%
+ {\beginlocalcontrol
+ \pushmacro\matchloopcommand
+ \def\matchloopcommand##1##2##3##4##5##6##7##8##9{#3}%
+ \endlocalcontrol
+ \the\ctxluamatch\matchloopcommand{#1}{#2}%
+ \beginlocalcontrol
+ \popmacro\matchloopcommand
+ \endlocalcontrol}
+\stoptyping
+
+Local control hides the assignments (it basically nests the mail loop).
+
+\stoptitle
+
+\starttitle[title=A few teasers (\TEX)]
+
+\starttyping[style=\small\tt]
+\doloopovermatch {(\letterpercent d+)} {this 1 is 22 a 333 test} { [#1] }
+
+\doloopovermatch {(\letterpercent w+) *(\letterpercent w*)} {aa bb cc dd} {
+ [
+ \doloopovermatch{(\letterpercent w)(\letterpercent w)} {#1} {(##1 ##2)}
+ \doloopovermatch{(\letterpercent w)(\letterpercent w)} {#2} {(##1 ##2)}
+ ]
+}
+
+\doloopovermatch
+ {(.-)\letterpercent{\bf (.-)\letterpercent}(.*)}
+ {this is {\bf a} test}
+ {#1{\it not #2}#3}
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=A few teasers (\LUA)]
+
+\starttyping[style=\small\tt]
+interfaces.implement {
+ name = "bitwisexor", public = true, usage = "value", actions =
+ function(what)
+ local a = tokens.scanners.cardinal()
+ scankeyword("with")
+ local b = tokens.scanners.cardinal()
+ if what == "value" then
+ return tokens.values.cardinal, a ~ b
+ else
+ logs.texerrormessage("you can't use \\bitwiseor this way")
+ end
+ end
+}
+interfaces.implement {
+ name = "ifbitwiseand", public = true, usage = "condition", actions =
+ function(what)
+ local a = tokens.scanners.cardinal()
+ local b = tokens.scanners.cardinal()
+ return tokens.values.boolean, (a & b) ~= 0
+ end
+}
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=Questions and more examples]
+
+More examples will be given in the editor.
+
+\stoptitle
+
+\stopdocument
+
+% \doloopovermatch {(\letterpercent w+) *(\letterpercent w*)} {aa bb cc dd} {
+% [
+% \doloopovermatch{(\letterpercent w)(\letterpercent w)} {#1} {(##1 ##2)}
+% \doloopovermatch{(\letterpercent w)(\letterpercent w)} {#2} {(##1 ##2)}
+% ]
+% }
+
+% \doloopovermatch {(\letterpercent d+)} {this 1 is 22 a 333 test} { [#1] }
+
+% \testfeatureonce{10000}{\doloopovermatch {(\letterpercent d+)} {this 1 is 22 a 333 test} {}} \elapsedtime
+
+% \doloopovermatch
+% {(.-)\letterpercent{\bf (.-)\letterpercent}(.*)}
+% {this is {\bf a} test}
+% {#1{\it not #2}#3}
+
+% \doloopovermatch {([\letterpercent w]+)} {\cldloadfile{tufte.tex}} { [#1] }
+
+% \testfeatureonce{100}{\doloopovermatch {([\letterpercent w]+)}{\cldloadfile{tufte.tex}} {}} \elapsedtime
+
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-luametatex.pdf b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-luametatex.pdf
new file mode 100644
index 00000000000..fcb906f8b82
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-luametatex.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-luametatex.tex b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-luametatex.tex
new file mode 100644
index 00000000000..10b57660ea9
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-luametatex.tex
@@ -0,0 +1,529 @@
+% language=us
+
+\usemodule[present-boring,abbreviations-logos]
+
+\startdocument
+ [title={LUAMETATEX},
+ banner={where do we stand},
+ location={context\enspace {\bf 2020}\enspace meeting}]
+
+\starttitle[title=When it started]
+
+\startitemize
+
+\startitem
+ About three years ago the idea came up to go this route.
+\stopitem
+\startitem
+ At the 2018 meeting it was first mentioned and those present were okay with
+ it.
+\stopitem
+\startitem
+ Early 2019 the first beta release took place.
+\stopitem
+\startitem
+ At the 2019 meeting the first more official version was presented.
+\stopitem
+\startitem
+ Around the 2020 meeting we have more or less arrived at what I had in mind.
+\stopitem
+\startitem
+ At the 2021 meeting I expect the code to be stable and repositories to be set
+ up.
+\stopitem
+\startitem
+ At the 2022 meeting we can make the official transition from \MKIV\ to \LMTX.
+\stopitem
+\startitem
+ Some new options are only enabled in my local \type {cont-exp.tex} file.
+\stopitem
+\startitem
+ Knowing that Wolfgang keeps an eye on all those changes makes me more daring.
+\stopitem
+\startitem
+ We aim to get less (but more efficient) macro code that on the average looks
+ better.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Why it started]
+
+\startitemize
+
+\startitem
+ There was an increasing pressure for a stable \LUATEX.
+\stopitem
+\startitem
+ There should be no more changes to the interfaces, no more extensions.
+\stopitem
+\startitem
+ One can run into interesting comments on the web (as usual), like
+ \startitemize[packed]
+ \startitem The \LUATEX\ program has \quote {many bugs}. \stopitem
+ \startitem The \LUATEX\ manual is bad. \stopitem
+ \startitem The \LUATEX\ program is too slow to be useful. \stopitem
+ \startitem The \LUATEX\ program will never end up in distributions. \stopitem
+ \startitem The \LUATEX\ project is funded and developed in a commercial setting. \stopitem
+ \stopitemize
+\stopitem
+\startitem
+ I won't comment on how I read these (demotivating) comments because \unknown
+\stopitem
+\startitem
+ \unknown\ it anyway often says more about the writer (attitudes) than about
+ \LUATEX.
+\stopitem
+\startitem
+ I also looks like (non \CONTEXT) users are charmed by \LUATEX, and the more
+ they code, the more we need to freeze.
+\stopitem
+\startitem
+ So, hopefully, the \LUAMETATEX\ development does not interfere badly with
+ developments outside the \CONTEXT\ community.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=The development]
+
+The summary on the next pages is partial. More can be found in articles and
+documents that come with the distribution.
+
+\startitemize
+
+\startitem
+ \LUATEX\ started out as \CWEB\ code \unknown\ that eventually became just
+ \CCODE\ \unknown\ which in \LUAMETATEX\ has been detached from the (complex)
+ infrastructure.
+\stopitem
+\startitem
+ The basic idea is to only keep the core of \TEX, but for instance font
+ loading, file handling and the backend are gone.
+\stopitem
+\startitem
+ As a consequence the code has been reorganized (shuffled around).
+\stopitem
+\startitem
+ I experimented a lot without bothering about usage elsewhere and I like the
+ result so far.
+\stopitem
+\startitem
+ The \CONTEXT\ distribution will at some point ship with the source.
+\stopitem
+
+\stopitemize
+
+\starttitle[title=File handling]
+
+\startitemize
+
+\startitem
+ All file handling goes via \LUA, also read and write related primitives.
+\stopitem
+\startitem
+ The same is true for terminal (console) handling.
+\stopitem
+\startitem
+ Part of that (the writing) was actually kind of extension code in \TEX\ and
+ partly a system dependency.
+\stopitem
+\startitem
+ The \ETEX\ pseudo file \type {\scantokens} primitive uses the same mechanism
+ as \LUA\ does.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=The macro machinery]
+
+\startitemize
+
+\startitem
+ There are extensions to the way macro arguments are handled (less clumsy
+ macros).
+\stopitem
+\startitem
+ There are extra if tests (makes for nicer macros).
+\stopitem
+\startitem
+ Else branches in conditions can be collapsed using \type {\orelse} and \type
+ {\orunless} which gives cleaner low level code.
+\stopitem
+\startitem
+ Tracing gives more detail about node properties and also shows attributes.
+\stopitem
+\startitem
+ Some new data carriers have been added that can be played with from \LUA .
+\stopitem
+\startitem
+ Macros can efficiently be frozen (new) and protected (redone) and the
+ concepts \quote {long} and \type {outer} are gone. \footnote {In \CONTEXT\
+ macros were always \type {\long} and never \type {\outer}. Most commands were
+ unexpandable (also in \MKII, pre \ETEX). So, users won't notice this.}
+\stopitem
+\startitem
+ Saving and restoring is somewhat more efficient (partly a side effect of
+ wider memory).
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Language]
+
+\startitemize
+
+\startitem
+ Language control settings now use less parameters but bit sets instead.
+\stopitem
+\startitem
+ Only basic parameters are stored in the format file now.
+\stopitem
+\startitem
+ There are all kind of small improvements.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Typesetting]
+
+\startitemize
+
+\startitem
+ Attributes (the lists and states) are implemented more efficiently.
+\stopitem
+\startitem
+ The paragraph state is stored with the paragraph.
+\stopitem
+\startitem
+ Paragraphs can be normalized and options are now set with bit sets.
+\stopitem
+\startitem
+ Boxes carry orientation related information (offsets, rotation, etc).
+\stopitem
+\startitem
+ Some nodes carry more information.
+\stopitem
+\startitem
+ Directions are mostly gone (it's up to the backend).
+\stopitem
+\startitem
+ Migrated content is optionally kept with boxes.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Math]
+
+\startitemize
+
+\startitem
+ Some math concepts have been extended (like prescripts and some more
+ control over styles).
+\stopitem
+\startitem
+ There are plenty of new control details.
+\stopitem
+\startitem
+ The math parameter settings obey grouping in a math list.
+\stopitem
+\startitem
+ We can have math in discretionaries in text and more advanced discretionaries
+ in math as well.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Fonts]
+
+\startitemize
+
+\startitem
+ Font specification information no longer uses the string pool (which saves a
+ lot).
+\stopitem
+\startitem
+ Of course we still have the basic font handler.
+\stopitem
+\startitem
+ We only store what is needed for traditional \TEX\ font handling.
+\stopitem
+\startitem
+ Virtual fonts are even more virtual (also a backend thing) so we can have
+ more features.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=The code]
+
+\startitemize
+
+\startitem
+ Artifacts from \PASCAL\ and \CWEB\ have been removed.
+\stopitem
+\startitem
+ Languages, fonts, marks etc are no longer \quote {register} based.
+\stopitem
+\startitem
+ The token interface is more abstract and no longer presents strange numbers.
+\stopitem
+\startitem
+ Some internals have been reconstructed because of cleaner \LUA\ interfacing.
+\stopitem
+\startitem
+ A side effect of this is better abstraction of the equivalent ranges.
+\stopitem
+\startitem
+ The code has been made more abstract (and looks easier in e.g. Visual Studio).
+\stopitem
+\startitem
+ The compile farm is used to check if compilation works out of the box.
+\stopitem
+\startitem
+ Compilation is fast and easy, otherwise this project was not possible.
+\stopitem
+\startitem
+ Readability of the code is constantly improved (the usual: has to look okay
+ in my editor).
+\stopitem
+\startitem
+ The code has been made mostly independent of specific operating system needs.
+\stopitem
+\startitem
+ Wide characters are dealt with in Windows interfaces.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Libraries]
+
+\startitemize
+
+\startitem
+ We really want to stay lean and mean: the engine is also a \LUA\ engine.
+\stopitem
+\startitem
+ All code is included, a few libraries are used, but these are small, old and
+ stable.
+\stopitem
+\startitem
+ In addition some helper libraries are made (including pplib by Pawel).
+\stopitem
+\startitem
+ What we ship is what you get: \CONTEXT\ will not depend on more than that.
+\stopitem
+\startitem
+ If something is updated (at all) the differences are checked first.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=The \LUA\ engine]
+
+\startitemize
+
+\startitem
+ We use the latest (even alpha) \LUA\ (5.4) because \LUAMETATEX\ is a good
+ test.
+\stopitem
+\startitem
+ There is no support for \LUAJIT\ and the \FFI\ interface is gone.
+\stopitem
+\startitem
+ There is a limited set of libraries that we support but no code is (and will
+ be) included.
+\stopitem
+\startitem
+ There are less callbacks (because we only have a frontend).
+\stopitem
+\startitem
+ There are more token scanners and some options have been added.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Efficiency]
+
+\startitemize
+
+\startitem
+ We benefit some more from the wider memory words (some constructs could go).
+\stopitem
+\startitem
+ The format file is smaller and not longer compressed.
+\stopitem
+\startitem
+ Memory management is now mostly dynamic and usage is much lower.
+\stopitem
+\startitem
+ There are more statistics (also as side effect of memory management).
+\stopitem
+\startitem
+ Dumping the format has been made a bit more robust and is faster.
+\stopitem
+\startitem
+ The core engine performs a bit better (machines don't get that much faster).
+\stopitem
+\startitem
+ We want to be prepared for future architectures.
+\stopitem
+\startitem
+ We manage to keep the binary way below 3 MB.
+\stopitem
+\startitem
+ The lot runs quite well on e.g.\ a Raspberry Pi 4.
+\stopitem
+
+\stopitemize
+
+\starttitle[title=Upgraded \METAPOST]
+
+\startitemize
+
+\startitem
+ All (eight bit) font stuff has been stripped from the \METAPOST\ library.
+\stopitem
+\startitem
+ The library no longer has a \POSTSCRIPT\ backend.
+\stopitem
+\startitem
+ The library provides scanners that make extensions possible.
+\stopitem
+\startitem
+ All file \IO\ goes via \LUA.
+\stopitem
+\startitem
+ There are a few additions like pre|/|postscripts for clip and bounding boxes.
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Praise for the users]
+
+\startitemize
+
+\startitem
+ Much has been done and I probably forget to mention a lot.
+\stopitem
+\startitem
+ The number of bugs is relative small compared to what gets changed and added.
+\stopitem
+\startitem
+ The test suite gets ran very often, also to check if performance is okay.
+\stopitem
+\startitem
+ I could only do this because the \CONTEXT\ users are so tolerant.
+\stopitem
+\startitem
+ Some seem to constantly check for updates so they help with fast testing.
+\stopitem
+\startitem
+ The \CONTEXT\ code base gets stepwise adapted (split files) which again
+ forces users to test.
+\stopitem
+\startitem
+ It takes a lot of time because we take small steps in order not to mess up.
+\stopitem
+\startitem
+ I would not do it without the positive attribute of the \CONTEXT\ users.
+\stopitem
+\startitem
+ It's all about motivation and I thank the \CONTEXT\ users for providing this
+ friendly and non|-|competitive bubble!
+\stopitem
+
+\stopitemize
+
+\starttitle[title=Todo]
+
+\startitemize
+
+\startitem
+ Maybe add some more sanity checks in order to catch errors intruded by
+ callbacks. Maybe add some more tracing too.
+\stopitem
+\startitem
+ Explore variants, like having registers in dedicated eqtb tables so that we
+ can allocate them dynamically (mostly for the fun of doing it).
+\stopitem
+\startitem
+ Add some more documentation (read: addition cq.\ remarks about where the
+ original documentation no longer applies, but we have years for doing that).
+\stopitem
+\startitem
+ Update the manual (which is done occasionally in batch based on print|-|outs;
+ there is no real need to hurry because we still experiment).
+\stopitem
+\startitem
+ Apply some of the new stuff in \LMTX. Take up some challenges.
+\stopitem
+\startitem
+ Wrap up new functionality (once it's stable) in articles and other documents.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=And \LUATEX ?]
+
+\startitemize
+
+\startitem
+ Of course \LUATEX\ will be maintained! After all, \MKIV\ needs it and it
+ serves as reference for the front|-|end rendering and back|-|end generation
+ when we're messing with \LUAMETATEX.
+\stopitem
+\startitem
+ It is used by \LATEX\ and there are now also plain inspired packages. Because
+ there are spin|-|offs (\LATEX\ has settled on a version with built|-|in font
+ processing) we cannot change much.
+\stopitem
+\startitem
+ And \LUATEX\ being nicely integrated into \TEXLIVE\ is another argument for
+ not touching it too much.
+\stopitem
+\startitem
+ I have no clue of \LUATEX\ usage but that fact alone already makes an
+ argument for being even more careful. It's bad advertisement for \TEX\ when
+ users who use the low level interfaces get confronted with conceptual
+ changes.
+\stopitem
+\startitem
+ So in the end not much will be back ported to \LUATEX: at some point the code
+ base became too different and it's the price paid for the stability demand.
+ That way we cannot introduce new bugs either. It also doesn't pay of.
+\stopitem
+\startitem
+ But, a few non|-|intrusive things might actually trickle into it in due time,
+ also out of self interest: it might help to share code between \MKIV\ and
+ \LMTX.
+\stopitem
+
+\stopitemize
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mkii-mkiv-mkxl.pdf b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mkii-mkiv-mkxl.pdf
new file mode 100644
index 00000000000..1932da3940a
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mkii-mkiv-mkxl.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mkii-mkiv-mkxl.tex b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mkii-mkiv-mkxl.tex
new file mode 100644
index 00000000000..a0e119e755d
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mkii-mkiv-mkxl.tex
@@ -0,0 +1,208 @@
+% language=us
+
+\usemodule[present-boring,abbreviations-logos]
+
+\startdocument
+ [title={MKII MKIV LMTX},
+ banner={where does it end},
+ location={context\enspace {\bf 2020}\enspace meeting}]
+
+\starttitle[title=Welcome]
+
+This meeting was kind of special because of the Covid situations. It forces us to
+adapt and think about how to deal with this kind of situations. But, we had a
+very nice meeting as usual. The first talk was a summary of where we started and
+where we are now. The other talks are more specialized.
+
+All presentations use the same simple style. No interaction, no fancy \PDF\
+features, also because we had to stream them.
+
+\stoptitle
+
+\starttitle[title=MKII]
+
+\startitemize
+\startitem
+ In the 80's I bought the \TEX book but it all stayed pretty abstract.
+\stopitem
+\startitem
+ In the beginning of the 90's we had to get some math on paper we bought (!) a
+ copy of \LATEX.
+\stopitem
+\startitem
+ Right from the start we had to make in look a bit better than out of the box.
+\stopitem
+\startitem
+ So a shell around if evolved but soon we started from scratch.
+\stopitem
+\startitem
+ We did so first on top \LAMSTEX, then we switched to \INRSTEX.
+\stopitem
+\startitem
+ Soon we only used a few components of that: we learned from trial and error.
+\stopitem
+\startitem
+ We joined the \NTG, met Taco and friends, and slowly got some presence.
+\stopitem
+\startitem
+ And it all went on till we had what we later called \MKII.
+\stopitem
+\startitem
+ But, we always had ideas about what more we wanted.
+\stopitem
+\startitem
+ We went from \TEX\ to \ETEX\ to \PDFTEX\ to \PDFETEX.
+\stopitem
+\startitem
+ We played with the idea of \type {eetex}, different backends etc.\ (show old
+ \MAPS\ article).
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=MK{\thinspace\periods[2]}]
+
+\startitemize
+\startitem
+ \CONTEXT\ has been keyword driven and class based from the start.
+\stopitem
+\startitem
+ This came with a performance hit so the reputation was that it was slow:
+ inheritance, flexibility, user control \unknown\ it all comes at a price.
+\stopitem
+\startitem
+ \CONTEXT\ always had an abstract driver model (\DVIPS, \DVIPSONE, \DVIWINDO,
+ \ACROBAT, \PDFTEX, etc).
+\stopitem
+\startitem
+ It also had an adaptive the front end so we could support successive engines:
+ \TEX, \ETEX, \PDFTEX, \ALEPH, \XETEX.
+\stopitem
+\startitem
+ There had to be color and graphics support from the beginning.
+\stopitem
+\startitem
+ The interfaces permitted extension without breaking compatibility. The user
+ interface was multilingual: we started with Dutch and German (users).
+\stopitem
+\startitem
+ It came with management tools (like \TEXEXEC, \TEXUTIL, \TEXFONT, \TEXMFSTART) etc.\
+ for job control, dealing with (user) fonts, image manipulations etc.
+\stopitem
+\startitem
+ And of course \METAPOST, \XML, combining font setups, mixing encodings, \UTF\
+ patterns evolved with the system.
+\stopitem
+\startitem
+ Educational usage was often the reason for new features.
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=MKIV]
+
+\startitemize
+\startitem
+ At some point we started playing with \LUA\ (in \SCITE).
+\stopitem
+\startitem
+ And then with Hartmut started adding some basic \LUA\ support to a clone of
+ \PDFTEX\ that soon became \LUATEX.
+\stopitem
+\startitem
+ Next the Oriental \TEX\ project provided means for Taco to transition to
+ \CCODE .
+\stopitem
+\startitem
+ And for years we slowly built up the system. A \LUAJITTEX\ version showed up
+ and Luigi took over integration in \TEXLIVE\ (like compilation within the
+ infrastructure and updating libraries).
+\stopitem
+\startitem
+ In parallel we tested features and explored what we needed with \CONTEXT:
+ \MKIV\ evolved.
+\stopitem
+\startitem
+ And \unknown\ soon, all further development happened in \MKIV\ only: \MKII\
+ became frozen.
+\stopitem
+\startitem
+ The interface subsystem was upgraded and Wolfgang checked and completed all
+ setups while we did. Obsolete (font, language, input) mechanisms were
+ removed.
+\stopitem
+\startitem
+ A lot happened: some more \TEX, lots of \LUA, better \METAPOST\ integration,
+ more advanced \XML.
+\stopitem
+\startitem
+ To some extend a project like that became to late because the glory days of
+ \TEX\ were already past (publishing changed) but just as with \PDFTEX\ a
+ conceptual upgrade like was felt needed.
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=MKXL (aka LMTX)]
+
+\startitemize
+\startitem
+ When \LUATEX\ had to be frozen a follow up took place in \LUAMETATEX. The name
+ reflects the importance of each core component.
+\stopitem
+\startitem
+ The idea is to have an lean and mean engine, one that will become very stable
+ and does not depend on the issues of the day.
+\stopitem
+\startitem
+ It's for all those dedicated users who like quality and playing around but
+ also want guarantees that the tools keeps working years from now: it's about
+ independence.
+\stopitem
+\startitem
+ Of course we tested and explored with \CONTEXT\ and this time \LMTX\ evolves.
+ Here the \type {X} reflects that we consider \XML\ to be part of the picture.
+\stopitem
+\startitem
+ Although there will be (and already is) new functionality the change is less
+ dramatic because this we don't have the change in fonts, encoding and regime
+ subsystems (which made some \MKII\ commands go away).
+\stopitem
+\startitem
+ Hopefully some of the more tricky (hard to do in good old \TEX) mechanisms
+ can be improved now.
+\stopitem
+\startitem
+ And at some point we will freeze \MKIV\ and development will happen in \LMTX\
+ only.
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=This meeting]
+
+\startitemize
+\startitem
+ My talks in this meeting are mostly about \LUAMETATEX\ and the \CONTEXT\
+ version \LMTX\ that targets it: how it is done, which concepts show up, where
+ we want to go.
+\stopitem
+\startitem
+ Unless you kept a close eye on last years development, you will encounter of
+ plenty of new features that relate to \LUAMETATEX. So, there is more to tell,
+ but most of that is already known from previous meetings.
+\stopitem
+\startitem
+ And, as usual, a \CONTEXT\ meeting is not only a deadline, but also a
+ starting point. It's you who keep it all going. And, even more than that,
+ it is about us meeting.
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mp.pdf b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mp.pdf
new file mode 100644
index 00000000000..a86dc2d71fa
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mp.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mp.tex b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mp.tex
new file mode 100644
index 00000000000..6d2f640fb03
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-mp.tex
@@ -0,0 +1,342 @@
+% language=us
+
+\usemodule[present-boring,abbreviations-logos]
+
+\startdocument
+ [title={METAFUN},
+ banner={simple fonts},
+ location={context\enspace {\bf 2020}\enspace meeting}]
+
+\starttitle[title=Metafonts]
+
+\startitemize
+
+\startitem
+ Because \METAPOST\ is based on \METAFONT\ it make sense to use of for making fonts.
+\stopitem
+
+\startitem
+ Making a font is an art in itself, something that is actually proven by many bad
+ looking fonts, but we have plenty of choice nowadays.
+\stopitem
+
+\startitem
+ We tend to use free fonts and often being made by volunteers we can hardly have any
+ demands.
+\stopitem
+
+\startitem
+ So, instead of complaining (which is not nice anyway) we can try to (at least temporary)
+ come up with a solution ourselves.
+\stopitem
+
+\startitem
+ We're actually talking about missing glyphs here and \METAPOST\ can be of help.
+\stopitem
+
+\startitem
+ Also keep in mind that we always had this option or variants of it in \CONTEXT, it's
+ just that we can make nicer interfaces now.
+\stopitem
+
+\startitem
+ So, don't expect something spectacular.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=What is is not]
+
+Years ago mechanisms were added to \MKIV\ to come up with more fancy shapes in
+for instance math. Actually Alan needed it and I wanted a root symbol to look
+like school times.
+
+\startbuffer
+\useMPlibrary[mat]
+
+\setupmathradical[color=darkgray,alternative=mp]
+
+% \definemathradical [sqrt] [mp=minifun::math:radical:default]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+So:
+
+\startbuffer
+\scale[height=2cm]{$ \sqrt {a+b+c+d} $}
+\stopbuffer
+
+\typebuffer
+
+Gives:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+\page
+
+And with:
+
+\startbuffer
+\startuniqueMPgraphic{minifun::math:radical:default}
+draw
+ math_radical_simple(OverlayWidth,OverlayHeight,OverlayDepth,OverlayOffset)
+ withpen pencircle
+ xscaled (2OverlayLineWidth)
+ yscaled (1OverlayLineWidth/4)
+ rotated 30
+ dashed evenly
+ withcolor OverlayLineColor ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\typebuffer
+
+We get
+
+\startlinecorrection
+\getbuffer
+\scale[height=2cm]{$ \sqrt {a+b+c+d} $}
+\stoplinecorrection
+
+\page
+
+Also think of stackers:
+
+\startbuffer
+\setupmathstackers [both] [color=darkgray,alternative=mp]
+\setupmathstackers [top] [color=darkgray,alternative=mp]
+\setupmathstackers [bottom] [color=darkgray,alternative=mp]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\blank[2*line]
+
+\startbuffer
+$
+ \overbracket {a+b+c+d} \quad
+ \underbracket {a+b+c+d} \quad
+ \doublebracket {a+b+c+d}
+$
+\blank
+$
+ \overparent {a+b+c+d} \quad
+ \underparent {a+b+c+d} \quad
+ \doubleparent {a+b+c+d}
+$
+\blank
+$
+ \overbrace {a+b+c+d} \quad
+ \underbrace {a+b+c+d} \quad
+ \doublebrace {a+b+c+d}
+$
+\blank
+$
+ \overbar {a+b+c+d} \quad
+ \underbar {a+b+c+d} \quad
+ \doublebar {a+b+c+d}
+$
+\blank
+$
+ \overleftarrow {a+b+c+d} \quad
+ \overrightarrow {a+b+c+d}
+$
+\blank
+$
+ \underleftarrow {a+b+c+d} \quad
+ \underrightarrow {a+b+c+d}
+$
+\stopbuffer
+
+\getbuffer
+
+\blank[2*line]
+
+But, these are just overlays and nothing special: we simply don't use the normal
+font route not fancy \LUA\ tricks either (in principle \MKII\ could do this). I
+might upgrade it some day (no real demand so far, just fun stuff).
+
+\stoptitle
+
+\starttitle[title=Real fonts]
+
+\startitemize
+
+\startitem For text we need an efficient way to define extra shapes. \stopitem
+\startitem We don't really want inline graphics every time we use a glyph. \stopitem
+\startitem We also want to cut and paste properly. \stopitem
+\startitem Basically the fact that we drop in shapes should be hidden. \stopitem
+
+\blank[2*line]
+
+\startitem
+ We use the same (generic) subsystem that is also used for color fonts, bitmap
+ emoji, \SVG\ fonts, etc.
+\stopitem
+\startitem
+ Shapes end up as \TYPETHREE\ fonts. These have some specific properties and
+ limitations, but we can actually make \UNICODE\ fonts.
+\stopitem
+\startitem
+ The system is not burdened by much overhead and most happens at embedding time.
+\stopitem
+
+\stopitemize
+
+\page
+
+\startbuffer[font]
+\definefont[DemoFontA][Serif*default @ 10pt]
+\definefont[DemoFontB][Serif*default @ 12pt]
+\definefont[DemoFontC][Serif*default @ 14pt]
+\definefont[DemoFontD][SerifBold*default @ 14pt]
+\stopbuffer
+
+\typebuffer[font] \getbuffer[font]
+
+\startbuffer[demo]
+\startlines
+\DemoFontA first\endash second\emdash third\char"2015\relax fourth
+\DemoFontB first\endash second\emdash third\char"2015\relax fourth
+\DemoFontC first\endash second\emdash third\char"2015\relax fourth
+\DemoFontD first\endash second\emdash third\char"2015\relax fourth
+\stoplines
+\stopbuffer
+
+\typebuffer[demo] \getbuffer[demo]
+
+\page
+
+\startbuffer[mpone]
+\startMPcalculation{simplefun}
+
+ vardef QuotationDashOne =
+ draw image (
+ interim linecap := squared ;
+ save l ; l := 0.2 ;
+ draw (l/2,3) -- (10-l/2,3) withpen pencircle scaled l ;
+ )
+ enddef ;
+
+ lmt_registerglyphs [
+ name = "symbolsone",
+ units = 10,
+ usecolor = true,
+ width = 10,
+ height = 3.1,
+ depth = 0,
+ ] ;
+
+ lmt_registerglyph [
+ category = "symbolsone",
+ unicode = "0x2015",
+ code = "QuotationDashOne ;"
+ ] ;
+
+\stopMPcalculation
+\stopbuffer
+
+\getbuffer[mpone]
+
+\startbuffer[font]
+\definefontfeature[exampleone][metapost=symbolsone]
+
+\definefont[DemoFontA][Serif*default,exampleone @ 10pt]
+\definefont[DemoFontB][Serif*default,exampleone @ 12pt]
+\definefont[DemoFontC][Serif*default,exampleone @ 14pt]
+\definefont[DemoFontD][SerifBold*default,exampleone @ 14pt]
+\stopbuffer
+
+\typebuffer[font] \getbuffer[font]
+
+\getbuffer[demo]
+
+\page
+
+\typebuffer[mpone][style=\tt\small\small]
+
+\page
+
+\startbuffer[mptwo]
+\startMPcalculation{simplefun}
+
+ vardef QuotationDashTwo =
+ draw image (
+ interim linecap := squared ;
+ save l ; l := 0.4 ;
+ string weight ; weight := getparameter "mpsfont" "parentdata" "shared" "rawdata" "metadata" "weight" ;
+ if weight = "semibold" : l := l * 2;
+ elseif weight = "bold" : l := l * 3; fi
+ draw (l/2,3) -- (10-l/2,3) withpen pencircle scaled l
+ withcolor yellow ;
+ )
+ enddef ;
+
+ lmt_registerglyphs [
+ name = "symbolstwo",
+ units = 10,
+ usecolor = false,
+ width = 10,
+ height = 3.1,
+ depth = 0,
+ ] ;
+
+ lmt_registerglyph [
+ category = "symbolstwo",
+ unicode = "0x2015",
+ code = "QuotationDashTwo ;"
+ ] ;
+
+\stopMPcalculation
+\stopbuffer
+
+\getbuffer[mptwo]
+
+\startbuffer[font]
+\definefontfeature[exampletwo][metapost=symbolstwo]
+
+\definefont[DemoFontA][Serif*default,exampletwo @ 10pt]
+\definefont[DemoFontB][Serif*default,exampletwo @ 12pt]
+\definefont[DemoFontC][Serif*default,exampletwo @ 14pt]
+\definefont[DemoFontD][SerifBold*default,exampletwo @ 14pt]
+\stopbuffer
+
+\typebuffer[font] \getbuffer[font]
+
+\getbuffer[demo]
+
+\page
+
+\typebuffer[mptwo][style=\tt\small\small]
+
+\stoptitle
+
+\starttitle[title=More examples]
+
+We give some examples (these are also in the modules). Overloading math
+symbols:
+
+\starttyping
+meta-imp-kindergarten.mkxl
+\stoptyping
+
+Extending fonts with Don Knuths dices and tiles (symbols, ligatures, proper
+\UNICODE):
+
+\starttyping
+meta-imp-gamesymbols.mkxl
+\stoptyping
+
+An implementation of Don Knuths ThirtySix font in various variants (color,
+random, shapes):
+
+\starttyping
+meta-imp-threesix.mkxl
+\stoptyping
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-sin.svg b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-sin.svg
new file mode 100644
index 00000000000..2d1f844386f
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-sin.svg
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="windows-1252" standalone="no"?>
+<svg
+ width="600" height="480"
+ viewBox="0 0 600 480"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+>
+
+<title>Gnuplot</title>
+<desc>Produced by GNUPLOT 5.2 patchlevel 8 </desc>
+
+<g id="gnuplot_canvas">
+
+<rect x="0" y="0" width="600" height="480" fill="none"/>
+<defs>
+
+ <circle id='gpDot' r='0.5' stroke-width='0.5' stroke='currentColor'/>
+ <path id='gpPt0' stroke-width='0.222' stroke='currentColor' d='M-1,0 h2 M0,-1 v2'/>
+ <path id='gpPt1' stroke-width='0.222' stroke='currentColor' d='M-1,-1 L1,1 M1,-1 L-1,1'/>
+ <path id='gpPt2' stroke-width='0.222' stroke='currentColor' d='M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1'/>
+ <rect id='gpPt3' stroke-width='0.222' stroke='currentColor' x='-1' y='-1' width='2' height='2'/>
+ <rect id='gpPt4' stroke-width='0.222' stroke='currentColor' fill='currentColor' x='-1' y='-1' width='2' height='2'/>
+ <circle id='gpPt5' stroke-width='0.222' stroke='currentColor' cx='0' cy='0' r='1'/>
+ <use xlink:href='#gpPt5' id='gpPt6' fill='currentColor' stroke='none'/>
+ <path id='gpPt7' stroke-width='0.222' stroke='currentColor' d='M0,-1.33 L-1.33,0.67 L1.33,0.67 z'/>
+ <use xlink:href='#gpPt7' id='gpPt8' fill='currentColor' stroke='none'/>
+ <use xlink:href='#gpPt7' id='gpPt9' stroke='currentColor' transform='rotate(180)'/>
+ <use xlink:href='#gpPt9' id='gpPt10' fill='currentColor' stroke='none'/>
+ <use xlink:href='#gpPt3' id='gpPt11' stroke='currentColor' transform='rotate(45)'/>
+ <use xlink:href='#gpPt11' id='gpPt12' fill='currentColor' stroke='none'/>
+ <path id='gpPt13' stroke-width='0.222' stroke='currentColor' d='M0,1.330 L1.265,0.411 L0.782,-1.067 L-0.782,-1.076 L-1.265,0.411 z'/>
+ <use xlink:href='#gpPt13' id='gpPt14' fill='currentColor' stroke='none'/>
+ <filter id='textbox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
+ <feFlood flood-color='white' flood-opacity='1' result='bgnd'/>
+ <feComposite in='SourceGraphic' in2='bgnd' operator='atop'/>
+ </filter>
+ <filter id='greybox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
+ <feFlood flood-color='lightgrey' flood-opacity='1' result='grey'/>
+ <feComposite in='SourceGraphic' in2='grey' operator='atop'/>
+ </filter>
+</defs>
+<g fill="none" color="white" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,444.0 L62.9,444.0 M575.0,444.0 L566.0,444.0 '/> <g transform="translate(45.6,447.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >-1</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,401.4 L62.9,401.4 M575.0,401.4 L566.0,401.4 '/> <g transform="translate(45.6,405.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >-0.8</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,358.8 L62.9,358.8 M575.0,358.8 L566.0,358.8 '/> <g transform="translate(45.6,362.7)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >-0.6</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,316.2 L62.9,316.2 M575.0,316.2 L566.0,316.2 '/> <g transform="translate(45.6,320.1)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >-0.4</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,273.6 L62.9,273.6 M575.0,273.6 L566.0,273.6 '/> <g transform="translate(45.6,277.5)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" >-0.2</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,231.0 L62.9,231.0 M575.0,231.0 L566.0,231.0 '/> <g transform="translate(45.6,234.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" > 0</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,188.5 L62.9,188.5 M575.0,188.5 L566.0,188.5 '/> <g transform="translate(45.6,192.4)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" > 0.2</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,145.9 L62.9,145.9 M575.0,145.9 L566.0,145.9 '/> <g transform="translate(45.6,149.8)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" > 0.4</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,103.3 L62.9,103.3 M575.0,103.3 L566.0,103.3 '/> <g transform="translate(45.6,107.2)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" > 0.6</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,60.7 L62.9,60.7 M575.0,60.7 L566.0,60.7 '/> <g transform="translate(45.6,64.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" > 0.8</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,18.1 L62.9,18.1 M575.0,18.1 L566.0,18.1 '/> <g transform="translate(45.6,22.0)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text><tspan font-family="Arial" > 1</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,444.0 L53.9,435.0 M53.9,18.1 L53.9,27.1 '/> <g transform="translate(53.9,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >-10</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M184.2,444.0 L184.2,435.0 M184.2,18.1 L184.2,27.1 '/> <g transform="translate(184.2,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" >-5</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M314.5,444.0 L314.5,435.0 M314.5,18.1 L314.5,27.1 '/> <g transform="translate(314.5,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" > 0</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M444.7,444.0 L444.7,435.0 M444.7,18.1 L444.7,27.1 '/> <g transform="translate(444.7,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" > 5</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M575.0,444.0 L575.0,435.0 M575.0,18.1 L575.0,27.1 '/> <g transform="translate(575.0,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
+ <text><tspan font-family="Arial" > 10</tspan></text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,18.1 L53.9,444.0 L575.0,444.0 L575.0,18.1 L53.9,18.1 Z '/></g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+ <g id="gnuplot_plot_1" ><title>sin(x)</title>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <g transform="translate(507.9,40.0)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
+ <text>sin(x)</text>
+ </g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='rgb(148, 0, 211)' d='M516.2,36.1 L558.4,36.1 M53.9,115.2 L59.2,153.4 L64.4,194.8 L69.7,237.6 L75.0,280.2 L80.2,320.8
+ L85.5,357.7 L90.7,389.5 L96.0,414.8 L101.3,432.7 L106.5,442.3 L111.8,443.4 L117.1,435.8 L122.3,419.9
+ L127.6,396.3 L132.9,366.0 L138.1,330.2 L143.4,290.4 L148.6,248.2 L153.9,205.2 L159.2,163.3 L164.4,124.2
+ L169.7,89.4 L175.0,60.4 L180.2,38.3 L185.5,24.1 L190.8,18.2 L196.0,21.1 L201.3,32.4 L206.5,51.9
+ L211.8,78.6 L217.1,111.6 L222.3,149.3 L227.6,190.5 L232.9,233.2 L238.1,275.9 L243.4,316.8 L248.7,354.1
+ L253.9,386.5 L259.2,412.5 L264.4,431.2 L269.7,441.7 L275.0,443.7 L280.2,437.0 L285.5,421.9 L290.8,399.1
+ L296.0,369.4 L301.3,334.1 L306.6,294.6 L311.8,252.5 L317.1,209.6 L322.3,167.5 L327.6,128.0 L332.9,92.7
+ L338.1,63.0 L343.4,40.2 L348.7,25.1 L353.9,18.4 L359.2,20.4 L364.5,30.9 L369.7,49.6 L375.0,75.6
+ L380.2,108.0 L385.5,145.3 L390.8,186.2 L396.0,228.9 L401.3,271.6 L406.6,312.8 L411.8,350.5 L417.1,383.5
+ L422.4,410.2 L427.6,429.7 L432.9,441.0 L438.1,443.9 L443.4,438.0 L448.7,423.8 L453.9,401.7 L459.2,372.7
+ L464.5,337.9 L469.7,298.8 L475.0,256.9 L480.3,213.9 L485.5,171.7 L490.8,131.9 L496.0,96.1 L501.3,65.8
+ L506.6,42.2 L511.8,26.3 L517.1,18.7 L522.4,19.8 L527.6,29.4 L532.9,47.3 L538.2,72.6 L543.4,104.4
+ L548.7,141.3 L553.9,181.9 L559.2,224.5 L564.5,267.3 L569.7,308.7 L575.0,346.9 '/></g>
+ </g>
+<g fill="none" color="white" stroke="rgb(148, 0, 211)" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="black" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+ <path stroke='black' d='M53.9,18.1 L53.9,444.0 L575.0,444.0 L575.0,18.1 L53.9,18.1 Z '/></g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+</g>
+</g>
+</svg>
+
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-svg.pdf b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-svg.pdf
new file mode 100644
index 00000000000..39b0e00cb98
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-svg.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-svg.tex b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-svg.tex
new file mode 100644
index 00000000000..3860438e8a6
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-svg.tex
@@ -0,0 +1,123 @@
+% language=us
+
+\usemodule[present-boring,abbreviations-logos]
+
+\startdocument
+ [title={SVG GRAPHICS},
+ banner={some demos and discussion},
+ location={context\enspace {\bf 2020}\enspace meeting}]
+
+\starttitle[title=Wrapup]
+
+\startitemize
+
+\startitem
+ It expands to for Scalable Vector Graphics.
+\stopitem
+\startitem
+ It is an example of application \XML\ turned standard.
+\stopitem
+\startitem
+ It started out simple, kind of expanded \POSTSCRIPT\ in \XML\ format.
+\stopitem
+\startitem
+ It took a while to be picked up as output format.
+\stopitem
+
+\blank[2*line]
+
+\startitem
+ In practice you get the same messy build-up as in other vector formats.
+\stopitem
+
+\startitem
+ This is a side effect of often unstructured editing. \footnote {Afterwards
+ Hraban gave a demonstration of editing in InkScape and there was some
+ discussion about this aspect}.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Properties]
+
+\startitemize
+
+\startitem
+ Properties can be set as attributes to an element (key/values).
+\stopitem
+\startitem
+ Properties can be set in the \type {style} attribute (semicolon separated key/values).
+\stopitem
+\startitem
+ Properties can be set via one or more \type {class} assignments.
+\stopitem
+\startitem
+ Properties can be bound to a specific element
+\stopitem
+\startitem
+ Properties can be inherited from an ancestor (somewhat vague).
+\stopitem
+\startitem
+ Properties can be redundant (nested), overloaded (parent, style), editors can
+ add their own. etc.\ \unknown\ it's kind of a mess.
+\stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Side effects]
+
+\startbuffer
+\usemodule[gnuplot]
+
+\externalfigure
+ [context-2020-gpdemo.gp]
+ [conversion=svg,width=4cm,
+ background=color,backgroundcolor=white]
+
+\externalfigure
+ [context-2020-gpdemo.gp]
+ [conversion=svg,width=6cm,
+ background=color,backgroundcolor=white]
+
+\scale
+ [height=4cm]
+ {\framed
+ [background=color,backgroundcolor=white]
+ {\includegnuplotsvgfile[context-2020-sin.svg]}}
+
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\stoptitle
+
+\starttitle[title=Simple examples]
+
+Some examples were shown (they can be found in manuals):
+
+\starttyping
+svg-lmtx-context.lua
+svg-lmtx-microsoft.lua
+svg-lmtx-mozilla.lua
+svg-lmtx-xahlee.lua
+\stoptyping
+
+Also some examples were shown from the Math4All project.
+
+\stoptitle
+
+% \starttitle[title=Complex examples]
+%
+% \starttyping
+% temporary/svg/test*
+% \stoptyping
+%
+% \stoptitle
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-tokens.pdf b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-tokens.pdf
new file mode 100644
index 00000000000..c508d25ac24
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-tokens.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-tokens.tex b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-tokens.tex
new file mode 100644
index 00000000000..b987e2d107a
--- /dev/null
+++ b/Master/texmf-dist/doc/context/presentations/context/2020/context-2020-tokens.tex
@@ -0,0 +1,287 @@
+% language=us
+
+\usemodule[present-boring,abbreviations-logos,system-tokens]
+
+\startdocument
+ [title={TOKENS},
+ banner={tokens as I see them},
+ location={context\enspace {\bf 2020}\enspace meeting}]
+
+\starttitle[title=About tokens]
+
+\startitemize
+
+\startitem Like nodes, it's a common term used in programming. \stopitem
+\startitem In \TEX\ The Program tokens and nodes are therefore omni|-|present. \stopitem
+\startitem For most users they are irrelevant concepts. \stopitem
+\startitem But we will explain them anyway. \stopitem
+\startitem Let's try to avoid the snobbish token|-|speak sometimes heard in the community. \stopitem
+\startitem So \unknown\ I won't correct you as long as you don't correct me. \stopitem
+\startitem Let's now enter the world of tokens in the na\"ive way. \stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=What are tokens]
+
+\startitemize
+
+\startitem It is an internal data structure, effectively a (32 bit) integer. \stopitem
+\startitem This integer encodes a command (opcode) and an char code (operand). \stopitem
+\startitem But often it's not a character but more a sub command. \stopitem
+\startitem Input is converted into tokens. \stopitem
+\startitem Tokens are either expanded (interpreted) or stored. \stopitem
+\startitem When they are stored they are part of a larger data structure, a memory word. \stopitem
+\startitem Token memory is an array of such memory words. \stopitem
+\startitem The token memory \quote {word} has two integers: a token value and an index into token memory. \stopitem
+\startitem That way \TEX\ can have forward linked lists of tokens. \stopitem
+\startitem A hash table maps control sequences onto indices into token memory. \stopitem
+
+\stopitemize
+
+\starttitle[title=Some implementation details]
+
+\startitemize
+
+\startitem Sometimes there is special head token at the start. \stopitem
+\startitem A head token makes for easier appending of extra tokens. \stopitem
+\startitem Shared lists use the head node for a reference count. \stopitem
+\startitem Original \TEX\ uses global temporary lists. \stopitem
+\startitem This is needed when we expand (nested) and need to report issues. \stopitem
+\startitem This is not needed when we just serialize (which we do a lot in \LUATEX). \stopitem
+\startitem So, this is all optimized for performance and memory consumption. \stopitem
+\startitem Freed tokens are collected in a cache so tokens can get scattered. \stopitem
+\startitem In \LUAMETATEX\ we stay as close to original \TEX\ as possible. \stopitem
+\startitem But the \LUA\ interfaces force us to occasionally divert. \stopitem
+
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=A schematic view of tokens]
+
+A token value:
+
+\startlinecorrection[blank]
+ \setupTABLE[each][align=middle]
+ \setupTABLE[c][1][width=22mm]
+ \setupTABLE[c][2][width=42mm]
+ \bTABLE
+ \bTR \bTD cmd \eTD \bTD chr \eTD \eTR
+ \eTABLE
+\stoplinecorrection
+
+Token memory:
+
+\startlinecorrection[blank]
+ \setupTABLE[each][align=middle]
+ \setupTABLE[c][1][width=8mm]
+ \setupTABLE[c][2][width=64mm]
+ \setupTABLE[c][3][width=64mm]
+ \bTABLE
+ \bTR \bTD 1 \eTD \bTD info \eTD \bTD link \eTD \eTR
+ \bTR \bTD 2 \eTD \bTD info \eTD \bTD link \eTD \eTR
+ \bTR \bTD 3 \eTD \bTD info \eTD \bTD link \eTD \eTR
+ \bTR \bTD n \eTD \bTD info \eTD \bTD link \eTD \eTR
+ \eTABLE
+\stoplinecorrection
+
+\stoptitle
+
+\starttitle[title=Looking up control sequences]
+
+\startitemize
+
+\startitem A very visible to-be-token is a \type {\controlsequence}. \stopitem
+\startitem When read, the name will be looked up in the hash table. \stopitem
+\startitem When found its value will point to the table of equivalents. \stopitem
+\startitem That table keeps track of:
+ \startitemize
+ \startitem the type (cmd) \stopitem
+ \startitem the current level (grouping) \stopitem
+ \startitem the current meaning (token list) \stopitem
+ \stopitemize
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=The (big) table of equivalents (simplified)]
+
+\startlinecorrection[blank]
+ \bTABLE
+ \bTR \bTD[ny=4] main hash \eTD \bTD null control sequence \eTD \eTR
+ \bTR \bTD 128K hash entries \eTD \eTR
+ \bTR \bTD frozen control sequences \eTD \eTR
+ \bTR \bTD special sequences (undefined) \eTD \eTR
+ \bTR \bTD[ny=7] registers \eTD \bTD 17 internal & 64K user glues \eTD \eTR
+ \bTR \bTD 4 internal & 64K user mu glues \eTD \eTR
+ \bTR \bTD 12 internal & 64K user tokens \eTD \eTR
+ \bTR \bTD 2 internal & 64K user boxes \eTD \eTR
+ \bTR \bTD 116 internal & 64K user integers \eTD \eTR
+ \bTR \bTD 0 internal & 64K user attribute \eTD \eTR
+ \bTR \bTD 22 internal & 64K user dimensions \eTD \eTR
+ \bTR \bTD specifications \eTD \bTD 5 internal & 0 user \eTD \eTR
+ \bTR \bTD extra hash \eTD \bTD additional entries (grows dynamic) \eTD \eTR
+ \eTABLE
+\stoplinecorrection
+
+\stoptable
+
+\starttitle[title=The hash table (simplified)]
+
+The hash table runs parallel to the main hash. On the todo list is is to move the
+registers to its own tables and make them dynamic.
+
+\startlinecorrection[blank]
+ \setupTABLE[each][align=middle]
+ \setupTABLE[c][1][width=16mm]
+ \setupTABLE[c][2][width=64mm]
+ \setupTABLE[c][3][width=64mm]
+ \bTABLE
+ \bTR \bTD 1 \eTD \bTD string index \eTD \bTD equivalents or (next > n) index \eTD \eTR
+ \bTR \bTD 2 \eTD \bTD string index \eTD \bTD equivalents or (next > n) index \eTD \eTR
+ \bTR \bTD n \eTD \bTD string index \eTD \bTD equivalents or (next > n) index \eTD \eTR
+ \bTR \bTD n + 1 \eTD \bTD string index \eTD \bTD equivalents or (next > n) index \eTD \eTR
+ \bTR \bTD n + 2 \eTD \bTD string index \eTD \bTD equivalents or (next > n) index \eTD \eTR
+ \bTR \bTD n + m \eTD \bTD string index \eTD \bTD equivalents or (next > n) index \eTD \eTR
+ \eTABLE
+\stoplinecorrection
+
+Equivalents (registers direct, macros indirect i.e.\ token lists):
+
+\startlinecorrection[blank]
+ \setupTABLE[each][align=middle]
+ \setupTABLE[c][1][width=8mm]
+ \setupTABLE[c][2][width=32mm]
+ \setupTABLE[c][3][width=32mm]
+ \setupTABLE[c][4][width=64mm]
+ \bTABLE
+ \bTR \bTD 1 \eTD \bTD level \eTD \bTD type \eTD \bTD value \eTD \eTR
+ \bTR \bTD 2 \eTD \bTD level \eTD \bTD type \eTD \bTD value \eTD \eTR
+ \bTR \bTD 3 \eTD \bTD level \eTD \bTD type \eTD \bTD value \eTD \eTR
+ \bTR \bTD n \eTD \bTD level \eTD \bTD type \eTD \bTD value \eTD \eTR
+ \eTABLE
+\stoplinecorrection
+
+\stoptitle
+
+\starttitle[title=Other data management]
+
+\startitemize
+\startitem Grouping is handles by a nesting stack. \stopitem
+\startitem Nested conditionals (\type {\if...}) have their own stack. \stopitem
+\startitem The values before assignments are saved ion the save stack. \stopitem
+\startitem Also other local changes (housekeeping) ends up in the save stack. \stopitem
+\startitem Token lists and macro aliases have references pointers (reuse). \stopitem
+\startitem Attributes, being linked node lists, have their own management. \stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Example 1: in the input]
+
+\startbuffer
+\luatokentable{1 \bf{2} 3\what {!}}
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \getbuffer}
+
+\stoptitle
+
+\starttitle[title=Example 1: in the input]
+
+\startbuffer
+\luatokentable{a \the\scratchcounter b \the\parindent \hbox to 10pt{x}}
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \getbuffer}
+
+\stoptitle
+
+\starttitle[title=Example 2: user registers]
+
+\startbuffer
+\scratchtoks{foo \framed{\red 123}456}
+
+\luatokentable\scratchtoks
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \getbuffer}
+
+\stoptitle
+
+\starttitle[title=Example 3: internal variables]
+
+\startbuffer
+\luatokentable\everypar
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \getbuffer}
+
+\stoptitle
+
+\starttitle[title=Example 4: macro definitions]
+
+\startbuffer
+\protected\def\whatever#1[#2](#3)\relax{oeps #1 and #2 & #3 done ## error}
+
+\luatokentable\whatever
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \startcolumns \getbuffer \stopcolumns}
+
+\stoptitle
+
+\starttitle[title=Example 5: commands]
+
+\startbuffer
+\luatokentable\startitemize
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \getbuffer}
+
+\stoptitle
+
+\starttitle[title=Example 6: commands]
+
+\startbuffer
+\luatokentable\doifelse
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \getbuffer }
+
+\stoptitle
+
+\starttitle[title=Example 7: nothing]
+
+\startbuffer
+\luatokentable\relax
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \getbuffer }
+
+\stoptitle
+
+\starttitle[title=Example 8: Hashes]
+
+\startbuffer
+\edef\foo#1#2{(#1)(\letterhash)(#2)} \luatokentable\foo
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \getbuffer }
+
+\stoptitle
+
+\starttitle[title=Example 9: Nesting]
+
+\startbuffer
+\def\foo#1{\def\foo##1{(#1)(##1)}} \luatokentable\foo
+\stopbuffer
+
+\typebuffer \blank[line] {\switchtobodyfont[8pt] \getbuffer }
+
+\stoptitle
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.man b/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.man
index b024daf6686..3bb84f99026 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.man
@@ -1,4 +1,4 @@
-.TH "ctxtools" "1" "01-01-2020" "version 1.3.5" "CtxTools"
+.TH "ctxtools" "1" "01-01-2021" "version 1.3.5" "CtxTools"
.SH NAME
ctxtools - CtxTools
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.man b/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.man
index 9166bf1146c..8a78ea5aaca 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.man
@@ -1,4 +1,4 @@
-.TH "imgtopdf" "1" "01-01-2020" "version 1.1.2" "ImgToPdf"
+.TH "imgtopdf" "1" "01-01-2021" "version 1.1.2" "ImgToPdf"
.SH NAME
imgtopdf - ImgToPdf
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/pdftools.man b/Master/texmf-dist/doc/context/scripts/mkii/pdftools.man
index 2258f7fd6f9..477403320de 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/pdftools.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/pdftools.man
@@ -1,4 +1,4 @@
-.TH "pdftools" "1" "01-01-2020" "version 1.2.1" "PDFTools"
+.TH "pdftools" "1" "01-01-2021" "version 1.2.1" "PDFTools"
.SH NAME
pdftools - PDFTools
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.man b/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.man
index 2439d48a5b8..4e83555e5b8 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.man
@@ -1,4 +1,4 @@
-.TH "pstopdf" "1" "01-01-2020" "version 2.0.1" "PStoPDF"
+.TH "pstopdf" "1" "01-01-2021" "version 2.0.1" "PStoPDF"
.SH NAME
pstopdf - PStoPDF
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.man b/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.man
index 4c5a5c172a6..ccbfe325c37 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.man
@@ -1,4 +1,4 @@
-.TH "rlxtools" "1" "01-01-2020" "version 1.0.1" "RlxTools"
+.TH "rlxtools" "1" "01-01-2021" "version 1.0.1" "RlxTools"
.SH NAME
rlxtools - RlxTools
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texexec.man b/Master/texmf-dist/doc/context/scripts/mkii/texexec.man
index e783e8d6e47..e2935cc1778 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/texexec.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texexec.man
@@ -1,4 +1,4 @@
-.TH "texexec" "1" "01-01-2020" "version 6.2.1" "TeXExec"
+.TH "texexec" "1" "01-01-2021" "version 6.2.1" "TeXExec"
.SH NAME
texexec - TeXExec
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.man b/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.man
index 8118c9c7f7d..6ed2acf8a17 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.man
@@ -1,4 +1,4 @@
-.TH "mtxrun" "1" "01-01-2020" "version 1.33" "ConTeXt TDS Runner Tool"
+.TH "mtxrun" "1" "01-01-2021" "version 1.33" "ConTeXt TDS Runner Tool"
.SH NAME
mtxrun - ConTeXt TDS Runner Tool
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/textools.man b/Master/texmf-dist/doc/context/scripts/mkii/textools.man
index 4d5df1fa93c..832dfb21ff9 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/textools.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/textools.man
@@ -1,4 +1,4 @@
-.TH "textools" "1" "01-01-2020" "version 1.3.1" "TeXTools"
+.TH "textools" "1" "01-01-2021" "version 1.3.1" "TeXTools"
.SH NAME
textools - TeXTools
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texutil.man b/Master/texmf-dist/doc/context/scripts/mkii/texutil.man
index d30913ad51c..d2f2adb41ab 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/texutil.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texutil.man
@@ -1,4 +1,4 @@
-.TH "texutil" "1" "01-01-2020" "version 9.1.0" "TeXUtil"
+.TH "texutil" "1" "01-01-2021" "version 9.1.0" "TeXUtil"
.SH NAME
texutil - TeXUtil
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/tmftools.man b/Master/texmf-dist/doc/context/scripts/mkii/tmftools.man
index 731d6ed34ef..d51933e7353 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/tmftools.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/tmftools.man
@@ -1,4 +1,4 @@
-.TH "tmftools" "1" "01-01-2020" "version 1.1.0" "TMFTools"
+.TH "tmftools" "1" "01-01-2021" "version 1.1.0" "TMFTools"
.SH NAME
tmftools - TMFTools
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/xmltools.man b/Master/texmf-dist/doc/context/scripts/mkii/xmltools.man
index efea6a69bb8..fd6143769a3 100644
--- a/Master/texmf-dist/doc/context/scripts/mkii/xmltools.man
+++ b/Master/texmf-dist/doc/context/scripts/mkii/xmltools.man
@@ -1,4 +1,4 @@
-.TH "xmltools" "1" "01-01-2020" "version 1.2.2" "XMLTools"
+.TH "xmltools" "1" "01-01-2021" "version 1.2.2" "XMLTools"
.SH NAME
xmltools - XMLTools
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/context.html b/Master/texmf-dist/doc/context/scripts/mkiv/context.html
index 3262b91d1aa..682b8621fa6 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/context.html
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/context.html
@@ -14,7 +14,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
- <title>ConTeXt Process Management 1.03</title>
+ <title>ConTeXt Process Management 1.04</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">ConTeXt Process Management 1.03 </div>
+ <div id="top-two">ConTeXt Process Management 1.04 </div>
</div>
</div>
<div id="bottom"> <div id="bottom-one">
@@ -65,6 +65,7 @@
<tr><th>--errors</th><td>list</td><td>show errors at the end of a run, quit when in list (also when --silent)</td></tr>
<tr><th>--htmlerrorpage</th><td></td><td>generate html error page instead (optional: =scite)</td></tr>
<tr><th>--noconsole</th><td></td><td>disable logging to the console (logfile only)</td></tr>
+ <tr><th>--nodummy</th><td></td><td>don't create a dummy file (can confuse pdf viewers that keep file in view)</td></tr>
<tr><th>--purgeresult</th><td></td><td>purge result file before run</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--forcexml</th><td></td><td>force xml stub</td></tr>
@@ -75,6 +76,8 @@
<tr><th>--arrange</th><td></td><td>run extra imposition pass, given that the style sets up imposition</td></tr>
<tr><th>--noarrange</th><td></td><td>ignore imposition specifications in the style</td></tr>
<tr><th/><td/><td/></tr>
+ <tr><th>--pages</th><td></td><td>report pagenumbers of names pages and list references (--page=... or --page=...)</td></tr>
+ <tr><th/><td/><td/></tr>
<tr><th>--jit</th><td></td><td>use luajittex with jit turned off (only use the faster virtual machine)</td></tr>
<tr><th>--jiton</th><td></td><td>use luajittex with jit turned on (in most cases not faster, even slower)</td></tr>
<tr><th/><td/><td/></tr>
@@ -107,6 +110,7 @@
<tr><th>--keeptuc</th><td></td><td>keep previous tuc files (jobname-tuc-[run].tmp)</td></tr>
<tr><th>--keeplog</th><td></td><td>keep previous log files (jobname-log-[run].tmp)</td></tr>
<tr><th>--lmtx</th><td></td><td>force lmtx mode (when available)</td></tr>
+ <tr><th>--overloadmode=error|warning|0--6|255</th><td></td><td>enable csname overload checking</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--extra=name</th><td></td><td>process extra (mtx-context-... in distribution)</td></tr>
<tr><th>--extras</th><td></td><td>show extras</td></tr>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/context.man b/Master/texmf-dist/doc/context/scripts/mkiv/context.man
index 9b23bd88b6d..7d9e949bb16 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/context.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/context.man
@@ -1,4 +1,4 @@
-.TH "mtx-context" "1" "01-01-2020" "version 1.03" "ConTeXt Process Management"
+.TH "mtx-context" "1" "01-01-2021" "version 1.04" "ConTeXt Process Management"
.SH NAME
mtx-context - ConTeXt Process Management
.SH SYNOPSIS
@@ -77,6 +77,9 @@ generate html error page instead (optional: =scite)
.B --noconsole
disable logging to the console (logfile only)
.TP
+.B --nodummy
+don't create a dummy file (can confuse pdf viewers that keep file in view)
+.TP
.B --purgeresult
purge result file before run
.TP
@@ -98,6 +101,9 @@ run extra imposition pass, given that the style sets up imposition
.B --noarrange
ignore imposition specifications in the style
.TP
+.B --pages
+report pagenumbers of names pages and list references (--page=... or --page=...)
+.TP
.B --jit
use luajittex with jit turned off (only use the faster virtual machine)
.TP
@@ -171,6 +177,9 @@ keep previous log files (jobname-log-[run].tmp)
.B --lmtx
force lmtx mode (when available)
.TP
+.B --overloadmode=error|warning|0--6|255
+enable csname overload checking
+.TP
.B --extra=name
process extra (mtx-context-... in distribution)
.TP
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/context.xml b/Master/texmf-dist/doc/context/scripts/mkiv/context.xml
index 0c7038d2680..98a75244b12 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/context.xml
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/context.xml
@@ -4,7 +4,7 @@
<metadata>
<entry name="name">mtx-context</entry>
<entry name="detail">ConTeXt Process Management</entry>
- <entry name="version">1.03</entry>
+ <entry name="version">1.04</entry>
<entry name="comment">external helpinfo file</entry>
</metadata>
<flags>
@@ -82,6 +82,9 @@
<flag name="noconsole">
<short>disable logging to the console (logfile only)</short>
</flag>
+ <flag name="nodummy">
+ <short>don't create a dummy file (can confuse pdf viewers that keep file in view)</short>
+ </flag>
<flag name="purgeresult">
<short>purge result file before run</short>
</flag>
@@ -109,6 +112,11 @@
</flag>
</subcategory>
<subcategory>
+ <flag name="pages">
+ <short>report pagenumbers of names pages and list references (<ref name="page"/>=... or <ref name="page"/>=...)</short>
+ </flag>
+ </subcategory>
+ <subcategory>
<flag name="jit">
<short>use luajittex with jit turned off (only use the faster virtual machine)</short>
</flag>
@@ -200,6 +208,9 @@
<flag name="lmtx">
<short>force lmtx mode (when available)</short>
</flag>
+ <flag name="overloadmode=error|warning|0--6|255">
+ <short>enable csname overload checking</short>
+ </flag>
</subcategory>
<subcategory>
<flag name="extra=name">
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/luatools.man b/Master/texmf-dist/doc/context/scripts/mkiv/luatools.man
index 0d0392f396e..94bbd9fcab9 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/luatools.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/luatools.man
@@ -1,4 +1,4 @@
-.TH "luatools" "1" "01-01-2020" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
+.TH "luatools" "1" "01-01-2021" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
.SH NAME
luatools - ConTeXt TDS Management Tool (aka luatools)
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-babel.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-babel.man
index 5ac999c664b..621a1a4ab19 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-babel.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-babel.man
@@ -1,4 +1,4 @@
-.TH "mtx-babel" "1" "01-01-2020" "version 1.20" "Babel Input To UTF Conversion"
+.TH "mtx-babel" "1" "01-01-2021" "version 1.20" "Babel Input To UTF Conversion"
.SH NAME
mtx-babel - Babel Input To UTF Conversion
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-base.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-base.man
index 76f60696f48..3bfc0878434 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-base.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-base.man
@@ -1,4 +1,4 @@
-.TH "mtx-base" "1" "01-01-2020" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
+.TH "mtx-base" "1" "01-01-2021" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
.SH NAME
mtx-base - ConTeXt TDS Management Tool (aka luatools)
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-bibtex.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-bibtex.man
index 60bfd7e1d40..c44df3bbf3e 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-bibtex.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-bibtex.man
@@ -1,4 +1,4 @@
-.TH "mtx-bibtex" "1" "01-01-2020" "version 1.00" "bibtex helpers"
+.TH "mtx-bibtex" "1" "01-01-2021" "version 1.00" "bibtex helpers"
.SH NAME
mtx-bibtex - bibtex helpers
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-cache.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-cache.man
index e266d8da205..60d9450c194 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-cache.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-cache.man
@@ -1,4 +1,4 @@
-.TH "mtx-cache" "1" "01-01-2020" "version 1.01" "ConTeXt & MetaTeX Cache Management"
+.TH "mtx-cache" "1" "01-01-2021" "version 1.01" "ConTeXt & MetaTeX Cache Management"
.SH NAME
mtx-cache - ConTeXt & MetaTeX Cache Management
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-chars.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-chars.man
index ad52b5b8909..407b3258d0b 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-chars.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-chars.man
@@ -1,4 +1,4 @@
-.TH "mtx-chars" "1" "01-01-2020" "version 0.10" "MkII Character Table Generators"
+.TH "mtx-chars" "1" "01-01-2021" "version 0.10" "MkII Character Table Generators"
.SH NAME
mtx-chars - MkII Character Table Generators
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-check.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-check.man
index 0525aeb69e8..46f1e06f609 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-check.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-check.man
@@ -1,4 +1,4 @@
-.TH "mtx-check" "1" "01-01-2020" "version 0.10" "Basic ConTeXt Syntax Checking"
+.TH "mtx-check" "1" "01-01-2021" "version 0.10" "Basic ConTeXt Syntax Checking"
.SH NAME
mtx-check - Basic ConTeXt Syntax Checking
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-colors.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-colors.man
index 883d6957310..601572f9130 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-colors.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-colors.man
@@ -1,4 +1,4 @@
-.TH "mtx-colors" "1" "01-01-2020" "version 0.10" "ConTeXt Color Management"
+.TH "mtx-colors" "1" "01-01-2021" "version 0.10" "ConTeXt Color Management"
.SH NAME
mtx-colors - ConTeXt Color Management
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.html
index 3262b91d1aa..682b8621fa6 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.html
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.html
@@ -14,7 +14,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
- <title>ConTeXt Process Management 1.03</title>
+ <title>ConTeXt Process Management 1.04</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">ConTeXt Process Management 1.03 </div>
+ <div id="top-two">ConTeXt Process Management 1.04 </div>
</div>
</div>
<div id="bottom"> <div id="bottom-one">
@@ -65,6 +65,7 @@
<tr><th>--errors</th><td>list</td><td>show errors at the end of a run, quit when in list (also when --silent)</td></tr>
<tr><th>--htmlerrorpage</th><td></td><td>generate html error page instead (optional: =scite)</td></tr>
<tr><th>--noconsole</th><td></td><td>disable logging to the console (logfile only)</td></tr>
+ <tr><th>--nodummy</th><td></td><td>don't create a dummy file (can confuse pdf viewers that keep file in view)</td></tr>
<tr><th>--purgeresult</th><td></td><td>purge result file before run</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--forcexml</th><td></td><td>force xml stub</td></tr>
@@ -75,6 +76,8 @@
<tr><th>--arrange</th><td></td><td>run extra imposition pass, given that the style sets up imposition</td></tr>
<tr><th>--noarrange</th><td></td><td>ignore imposition specifications in the style</td></tr>
<tr><th/><td/><td/></tr>
+ <tr><th>--pages</th><td></td><td>report pagenumbers of names pages and list references (--page=... or --page=...)</td></tr>
+ <tr><th/><td/><td/></tr>
<tr><th>--jit</th><td></td><td>use luajittex with jit turned off (only use the faster virtual machine)</td></tr>
<tr><th>--jiton</th><td></td><td>use luajittex with jit turned on (in most cases not faster, even slower)</td></tr>
<tr><th/><td/><td/></tr>
@@ -107,6 +110,7 @@
<tr><th>--keeptuc</th><td></td><td>keep previous tuc files (jobname-tuc-[run].tmp)</td></tr>
<tr><th>--keeplog</th><td></td><td>keep previous log files (jobname-log-[run].tmp)</td></tr>
<tr><th>--lmtx</th><td></td><td>force lmtx mode (when available)</td></tr>
+ <tr><th>--overloadmode=error|warning|0--6|255</th><td></td><td>enable csname overload checking</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--extra=name</th><td></td><td>process extra (mtx-context-... in distribution)</td></tr>
<tr><th>--extras</th><td></td><td>show extras</td></tr>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.man
index 9b23bd88b6d..7d9e949bb16 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.man
@@ -1,4 +1,4 @@
-.TH "mtx-context" "1" "01-01-2020" "version 1.03" "ConTeXt Process Management"
+.TH "mtx-context" "1" "01-01-2021" "version 1.04" "ConTeXt Process Management"
.SH NAME
mtx-context - ConTeXt Process Management
.SH SYNOPSIS
@@ -77,6 +77,9 @@ generate html error page instead (optional: =scite)
.B --noconsole
disable logging to the console (logfile only)
.TP
+.B --nodummy
+don't create a dummy file (can confuse pdf viewers that keep file in view)
+.TP
.B --purgeresult
purge result file before run
.TP
@@ -98,6 +101,9 @@ run extra imposition pass, given that the style sets up imposition
.B --noarrange
ignore imposition specifications in the style
.TP
+.B --pages
+report pagenumbers of names pages and list references (--page=... or --page=...)
+.TP
.B --jit
use luajittex with jit turned off (only use the faster virtual machine)
.TP
@@ -171,6 +177,9 @@ keep previous log files (jobname-log-[run].tmp)
.B --lmtx
force lmtx mode (when available)
.TP
+.B --overloadmode=error|warning|0--6|255
+enable csname overload checking
+.TP
.B --extra=name
process extra (mtx-context-... in distribution)
.TP
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.xml
index 0c7038d2680..98a75244b12 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.xml
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.xml
@@ -4,7 +4,7 @@
<metadata>
<entry name="name">mtx-context</entry>
<entry name="detail">ConTeXt Process Management</entry>
- <entry name="version">1.03</entry>
+ <entry name="version">1.04</entry>
<entry name="comment">external helpinfo file</entry>
</metadata>
<flags>
@@ -82,6 +82,9 @@
<flag name="noconsole">
<short>disable logging to the console (logfile only)</short>
</flag>
+ <flag name="nodummy">
+ <short>don't create a dummy file (can confuse pdf viewers that keep file in view)</short>
+ </flag>
<flag name="purgeresult">
<short>purge result file before run</short>
</flag>
@@ -109,6 +112,11 @@
</flag>
</subcategory>
<subcategory>
+ <flag name="pages">
+ <short>report pagenumbers of names pages and list references (<ref name="page"/>=... or <ref name="page"/>=...)</short>
+ </flag>
+ </subcategory>
+ <subcategory>
<flag name="jit">
<short>use luajittex with jit turned off (only use the faster virtual machine)</short>
</flag>
@@ -200,6 +208,9 @@
<flag name="lmtx">
<short>force lmtx mode (when available)</short>
</flag>
+ <flag name="overloadmode=error|warning|0--6|255">
+ <short>enable csname overload checking</short>
+ </flag>
</subcategory>
<subcategory>
<flag name="extra=name">
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-dvi.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-dvi.man
index fe42cb23bd3..f5a46acd855 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-dvi.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-dvi.man
@@ -1,4 +1,4 @@
-.TH "mtx-dvi" "1" "01-01-2020" "version 0.01" "ConTeXt DVI Helpers"
+.TH "mtx-dvi" "1" "01-01-2021" "version 0.01" "ConTeXt DVI Helpers"
.SH NAME
mtx-dvi - ConTeXt DVI Helpers
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-epub.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-epub.man
index 0c0e26b4987..8c96f2a908b 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-epub.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-epub.man
@@ -1,4 +1,4 @@
-.TH "mtx-epub" "1" "01-01-2020" "version 1.10" "ConTeXt EPUB Helpers"
+.TH "mtx-epub" "1" "01-01-2021" "version 1.10" "ConTeXt EPUB Helpers"
.SH NAME
mtx-epub - ConTeXt EPUB Helpers
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-evohome.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-evohome.man
index 90de5613cdd..c68a3072a1f 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-evohome.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-evohome.man
@@ -1,4 +1,4 @@
-.TH "mtx-evohome" "1" "01-01-2020" "version 1.00" "Evohome Fetcher"
+.TH "mtx-evohome" "1" "01-01-2021" "version 1.00" "Evohome Fetcher"
.SH NAME
mtx-evohome - Evohome Fetcher
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fcd.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fcd.man
index 6bff46e0d77..1f0e99a2685 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fcd.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fcd.man
@@ -1,4 +1,4 @@
-.TH "mtx-fcd" "1" "01-01-2020" "version 1.00" "Fast Directory Change"
+.TH "mtx-fcd" "1" "01-01-2021" "version 1.00" "Fast Directory Change"
.SH NAME
mtx-fcd - Fast Directory Change
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-flac.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-flac.man
index b58582f043f..531a76fdb16 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-flac.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-flac.man
@@ -1,4 +1,4 @@
-.TH "mtx-flac" "1" "01-01-2020" "version 0.10" "ConTeXt Flac Helpers"
+.TH "mtx-flac" "1" "01-01-2021" "version 0.10" "ConTeXt Flac Helpers"
.SH NAME
mtx-flac - ConTeXt Flac Helpers
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fonts.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fonts.man
index b137418b909..44bdffa6451 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fonts.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fonts.man
@@ -1,4 +1,4 @@
-.TH "mtx-fonts" "1" "01-01-2020" "version 1.00" "ConTeXt Font Database Management"
+.TH "mtx-fonts" "1" "01-01-2021" "version 1.00" "ConTeXt Font Database Management"
.SH NAME
mtx-fonts - ConTeXt Font Database Management
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.man
index 4c9aa39e532..088ae186fe7 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.man
@@ -1,4 +1,4 @@
-.TH "mtx-grep" "1" "01-01-2020" "version 0.10" "Simple Grepper"
+.TH "mtx-grep" "1" "01-01-2021" "version 0.10" "Simple Grepper"
.SH NAME
mtx-grep - Simple Grepper
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.html
index 4098ccaa2a3..a23a19b7d1b 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.html
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.html
@@ -51,6 +51,7 @@
<tr><th>--raw</th><td></td><td>report commands to the console</td></tr>
<tr><th>--check</th><td></td><td>generate check file</td></tr>
<tr><th>--meaning</th><td></td><td>report the mening of commands</td></tr>
+ <tr><th>--tokens</th><td></td><td>show the internal representation of commands</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--toutf</th><td></td><td>replace named characters by utf</td></tr>
<tr><th>--preprocess</th><td></td><td>preprocess mkvi files to tex files [force,suffix]</td></tr>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.man
index d3531d45674..dfe416e78d7 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.man
@@ -1,4 +1,4 @@
-.TH "mtx-interface" "1" "01-01-2020" "version 0.13" "ConTeXt Interface Related Goodies"
+.TH "mtx-interface" "1" "01-01-2021" "version 0.13" "ConTeXt Interface Related Goodies"
.SH NAME
mtx-interface - ConTeXt Interface Related Goodies
.SH SYNOPSIS
@@ -41,6 +41,9 @@ generate check file
.B --meaning
report the mening of commands
.TP
+.B --tokens
+show the internal representation of commands
+.TP
.B --toutf
replace named characters by utf
.TP
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.xml
index 5faff850789..6ffd3af736d 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.xml
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.xml
@@ -22,6 +22,7 @@
<flag name="raw"><short>report commands to the console</short></flag>
<flag name="check"><short>generate check file</short></flag>
<flag name="meaning"><short>report the mening of commands</short></flag>
+ <flag name="tokens"><short>show the internal representation of commands</short></flag>
</subcategory>
<subcategory>
<flag name="toutf"><short>replace named characters by utf</short></flag>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-metapost.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-metapost.man
index 5b110d06cc5..997f3873334 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-metapost.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-metapost.man
@@ -1,4 +1,4 @@
-.TH "mtx-metapost" "1" "01-01-2020" "version 0.10" "MetaPost to PDF processor"
+.TH "mtx-metapost" "1" "01-01-2021" "version 0.10" "MetaPost to PDF processor"
.SH NAME
mtx-metapost - MetaPost to PDF processor
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-modules.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-modules.man
index 5eaff034ebf..6f2bfebcd7f 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-modules.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-modules.man
@@ -1,4 +1,4 @@
-.TH "mtx-modules" "1" "01-01-2020" "version 1.00" "ConTeXt Module Documentation Generators"
+.TH "mtx-modules" "1" "01-01-2021" "version 1.00" "ConTeXt Module Documentation Generators"
.SH NAME
mtx-modules - ConTeXt Module Documentation Generators
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-package.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-package.man
index 02671fa9563..92c1782635d 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-package.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-package.man
@@ -1,4 +1,4 @@
-.TH "mtx-package" "1" "01-01-2020" "version 0.10" "Distribution Related Goodies"
+.TH "mtx-package" "1" "01-01-2021" "version 0.10" "Distribution Related Goodies"
.SH NAME
mtx-package - Distribution Related Goodies
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-patterns.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-patterns.man
index 320a89e2250..d87f5887fdb 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-patterns.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-patterns.man
@@ -1,4 +1,4 @@
-.TH "mtx-patterns" "1" "01-01-2020" "version 0.20" "ConTeXt Pattern File Management"
+.TH "mtx-patterns" "1" "01-01-2021" "version 0.20" "ConTeXt Pattern File Management"
.SH NAME
mtx-patterns - ConTeXt Pattern File Management
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.man
index df5501b9534..1535c8af80f 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.man
@@ -1,4 +1,4 @@
-.TH "mtx-pdf" "1" "01-01-2020" "version 0.10" "ConTeXt PDF Helpers"
+.TH "mtx-pdf" "1" "01-01-2021" "version 0.10" "ConTeXt PDF Helpers"
.SH NAME
mtx-pdf - ConTeXt PDF Helpers
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-plain.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-plain.man
index 431db53a107..9874cf6c63d 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-plain.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-plain.man
@@ -1,4 +1,4 @@
-.TH "mtx-plain" "1" "01-01-2020" "version 1.00" "Plain TeX Runner"
+.TH "mtx-plain" "1" "01-01-2021" "version 1.00" "Plain TeX Runner"
.SH NAME
mtx-plain - Plain TeX Runner
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-profile.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-profile.man
index f520a9e139a..a04a23d6ec0 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-profile.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-profile.man
@@ -1,4 +1,4 @@
-.TH "mtx-profile" "1" "01-01-2020" "version 1.00" "ConTeXt MkIV LuaTeX Profiler"
+.TH "mtx-profile" "1" "01-01-2021" "version 1.00" "ConTeXt MkIV LuaTeX Profiler"
.SH NAME
mtx-profile - ConTeXt MkIV LuaTeX Profiler
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-rsync.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-rsync.man
index 60b87707303..510775ba6ce 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-rsync.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-rsync.man
@@ -1,4 +1,4 @@
-.TH "mtx-rsync" "1" "01-01-2020" "version 0.10" "Rsync Helpers"
+.TH "mtx-rsync" "1" "01-01-2021" "version 0.10" "Rsync Helpers"
.SH NAME
mtx-rsync - Rsync Helpers
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-scite.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-scite.man
index 2e83387f9df..fbe640f6e10 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-scite.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-scite.man
@@ -1,4 +1,4 @@
-.TH "mtx-scite" "1" "01-01-2020" "version 1.00" "Scite Helper Script"
+.TH "mtx-scite" "1" "01-01-2021" "version 1.00" "Scite Helper Script"
.SH NAME
mtx-scite - Scite Helper Script
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-server.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-server.man
index ee565d4164e..ea9e8fee950 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-server.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-server.man
@@ -1,4 +1,4 @@
-.TH "mtx-server" "1" "01-01-2020" "version 0.10" "Simple Webserver For Helpers"
+.TH "mtx-server" "1" "01-01-2021" "version 0.10" "Simple Webserver For Helpers"
.SH NAME
mtx-server - Simple Webserver For Helpers
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-texworks.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-texworks.man
index 67e84a4d7ba..64fbece5ab9 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-texworks.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-texworks.man
@@ -1,4 +1,4 @@
-.TH "mtx-texworks" "1" "01-01-2020" "version 1.00" "TeXworks Startup Script"
+.TH "mtx-texworks" "1" "01-01-2021" "version 1.00" "TeXworks Startup Script"
.SH NAME
mtx-texworks - TeXworks Startup Script
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.man
index 582898c1ac0..852fd8ce8e8 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.man
@@ -1,4 +1,4 @@
-.TH "mtx-timing" "1" "01-01-2020" "version 0.10" "ConTeXt Timing Tools"
+.TH "mtx-timing" "1" "01-01-2021" "version 0.10" "ConTeXt Timing Tools"
.SH NAME
mtx-timing - ConTeXt Timing Tools
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-tools.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-tools.man
index 6626110b711..e2a74d420e2 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-tools.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-tools.man
@@ -1,4 +1,4 @@
-.TH "mtx-tools" "1" "01-01-2020" "version 1.01" "Some File Related Goodies"
+.TH "mtx-tools" "1" "01-01-2021" "version 1.01" "Some File Related Goodies"
.SH NAME
mtx-tools - Some File Related Goodies
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-unicode.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-unicode.man
index 072ff371fa5..605d634898f 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-unicode.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-unicode.man
@@ -1,4 +1,4 @@
-.TH "mtx-unicode" "1" "01-01-2020" "version 1.02" "Checker for char-dat.lua"
+.TH "mtx-unicode" "1" "01-01-2021" "version 1.02" "Checker for char-dat.lua"
.SH NAME
mtx-unicode - Checker for char-dat.lua
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-unzip.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-unzip.man
index d67698c599c..98b17733485 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-unzip.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-unzip.man
@@ -1,4 +1,4 @@
-.TH "mtx-unzip" "1" "01-01-2020" "version 0.10" "Simple Unzipper"
+.TH "mtx-unzip" "1" "01-01-2021" "version 0.10" "Simple Unzipper"
.SH NAME
mtx-unzip - Simple Unzipper
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-update.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-update.man
index 35500fb6daa..ccff02f91f4 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-update.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-update.man
@@ -1,4 +1,4 @@
-.TH "mtx-update" "1" "01-01-2020" "version 1.03" "ConTeXt Minimals Updater"
+.TH "mtx-update" "1" "01-01-2021" "version 1.03" "ConTeXt Minimals Updater"
.SH NAME
mtx-update - ConTeXt Minimals Updater
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-vscode.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-vscode.man
index f1c886fa0f4..7ac13328f9f 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-vscode.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-vscode.man
@@ -1,4 +1,4 @@
-.TH "mtx-vscode" "1" "01-01-2020" "version 1.00" "vscode extension generator"
+.TH "mtx-vscode" "1" "01-01-2021" "version 1.00" "vscode extension generator"
.SH NAME
mtx-vscode - vscode extension generator
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-watch.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-watch.man
index 185dc64bc71..bfa525b4b86 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-watch.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-watch.man
@@ -1,4 +1,4 @@
-.TH "mtx-watch" "1" "01-01-2020" "version 1.00" "ConTeXt Request Watchdog"
+.TH "mtx-watch" "1" "01-01-2021" "version 1.00" "ConTeXt Request Watchdog"
.SH NAME
mtx-watch - ConTeXt Request Watchdog
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-youless.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-youless.man
index 6d4e8b1df82..e88c2d0e18c 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-youless.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-youless.man
@@ -1,4 +1,4 @@
-.TH "mtx-youless" "1" "01-01-2020" "version 1.100" "youless Fetcher"
+.TH "mtx-youless" "1" "01-01-2021" "version 1.100" "youless Fetcher"
.SH NAME
mtx-youless - youless Fetcher
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun.man
index 8118c9c7f7d..6ed2acf8a17 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun.man
@@ -1,4 +1,4 @@
-.TH "mtxrun" "1" "01-01-2020" "version 1.33" "ConTeXt TDS Runner Tool"
+.TH "mtxrun" "1" "01-01-2021" "version 1.33" "ConTeXt TDS Runner Tool"
.SH NAME
mtxrun - ConTeXt TDS Runner Tool
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/sources/general/leaflets/leaflet-mixing.tex b/Master/texmf-dist/doc/context/sources/general/leaflets/leaflet-mixing.tex
index 9f14525b380..8b86988cae2 100644
--- a/Master/texmf-dist/doc/context/sources/general/leaflets/leaflet-mixing.tex
+++ b/Master/texmf-dist/doc/context/sources/general/leaflets/leaflet-mixing.tex
@@ -2,7 +2,7 @@
%D is reserved for our own purpose. Be creative instead.
\setupbodyfont
- [plex,7pt]
+ [plex,4pt]
\setuppapersize
[A3,landscape]
diff --git a/Master/texmf-dist/doc/context/sources/general/magazines/mag-1105-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/magazines/mag-1105-mkiv.tex
new file mode 100644
index 00000000000..b068f517b38
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/magazines/mag-1105-mkiv.tex
@@ -0,0 +1,194 @@
+% 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.
+
+\bitwiseflip \normalizelinemode \plusthree
+
+\usemodule[magazine-basic,abr-02]
+
+\usemodule[scite]
+
+\startbuffer[abstract]
+ Here is yet another short example of a feature introduced in \CONTEXT\ \LMTX.
+ It is mostly meant as teaser: maybe users have additional demands for this
+ low level mechanisn.
+\stopbuffer
+
+\setuplayout
+ [backspace=20mm,
+ topspace=10mm]
+
+\startdocument
+ [title={Playing with boxes, a teaser},
+ author={Hans Hagen},
+ %affiliation=PRAGMA ADE,
+ date=August 2020,
+ number=1105 LMTX]
+
+When a paragraph is typeset in a vertical box, we get a bunch of lines pasted
+together. If you want to change something in the result, you can disassemble that
+box in detailed ways (in \LUA) but maybe it's something simple that you like to
+do. For that we have a an interface to the lines on such a box. We start with a
+few settings:
+
+\starttyping[option=TEX]
+\bitwiseflip \normalizelinemode \plusthree % indent and normalize
+\stoptyping
+
+These two settings will become default in \CONTEXT\ \LMTX, but here we need them in
+order to show some properties of boxes.
+
+\startbuffer[sample]
+\setbox0\ruledvbox \bgroup
+ \leftskip 10pt
+ \rightskip 20pt
+ \hangindent 40pt
+ \hangafter 2
+ \parindent 5pt
+ \parfillleftskip 80pt plus 1 fill
+ \parfillrightskip 40pt plus 1 fill
+ \input tufte
+\egroup
+\stopbuffer
+
+\typebuffer[sample][option=TEX]
+
+This box has a bit weird setup but we want to demonstrate something to it's okay:
+
+\startlinecorrection
+ \getbuffer[sample] \box0
+\stoplinecorrection
+
+
+In case you wonder, the left and right parskips are a \MKIV\ thing and supported
+in \LMTX\ in a more advanced way. The left one can be used to push the last line
+to the right.
+
+\startbuffer[overview]
+\dorecurse {\boxlines 0} {
+ [#1] (%
+ \the\boxlinewd 0 #1, \the\boxlineht 0 #1, \the\boxlinedp 0 #1,
+ \the\boxlinels 0 #1, \the\boxliners 0 #1,
+ \the\boxlinelh 0 #1, \the\boxlinerh 0 #1,
+ \the\boxlinein 0 #1, \the\boxlinelp 0 #1, \the\boxlinerp 0 #1
+ ) \par
+}
+\stopbuffer
+
+\typebuffer[overview][option=TEX]
+
+\getbuffer[sample]
+
+\startpacked \tt \txx
+ \getbuffer[overview]
+\stoppacked
+
+The properties of a line are: width, height and depth, left and right skip,
+applied left and right hang, indentation (of the first line), left and right
+filler of the last line. You can use the commands shown as other dimensions, so
+\type {\the} is only needed when you serialize a property.
+
+Some properties can be changed (others might follow later). Here we change the
+width of line four (the equal sign is optional):
+
+\startbuffer
+\the\boxlinewd 0 4 \space& \boxlinewd 0 4 = 40pt \the\boxlinewd 0 4
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get: \inlinebuffer . We can detach a line from the box. Here we put two lines
+in another box that gets assigned to a box register, and a third line is assigned
+to a box register as|-|is:
+
+\startbuffer
+\setbox2\ruledhbox{\copyboxline 0 2}
+\setbox4\ruledhbox{\boxline 0 4}
+\setbox6 \boxline 0 6
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+The result is:
+
+\startbuffer
+[2] [\box2] \par
+[4] [\box4] \par
+[6] [\box6] \par
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+ \startpacked
+ \getbuffer
+ \stoppacked
+\stoplinecorrection
+
+You can query the natural width, height and depth too:
+
+\startbuffer
+used width : \the\boxlinewd 0 5, natural width : \the\boxlinenw 0 5
+used heigth : \the\boxlineht 0 5, natural height : \the\boxlinenh 0 5
+used depth : \the\boxlinedp 0 5, natural depth : \the\boxlinend 0 5
+\stopbuffer
+
+\typebuffer[option=TEX] \startlines \getbuffer \stoplines
+
+Next we replace an existing line by a new line:
+
+\startbuffer
+\setboxline 0 3 \hbox {\darkred \bold This is a replacement line!}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+The original box is now:
+
+\startlinecorrection
+\box0
+\stoplinecorrection
+
+We can repack the box with the usual \TEX\ commands: \type {\vpack {\unvbox0}}
+but here we just did a \type {\box0}.
+
+An example of a more useful application is the following. First we fill a box:
+
+\startbuffer
+\setbox\scratchbox\ruledvbox \bgroup
+ \input ward
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+With little effort we can add line numbers:
+
+\startbuffer
+\ruledvbox \bgroup
+ \dorecurse {\boxlines \scratchbox} {%
+ \dontleavehmode
+ \strut
+ \llap{\hbox to 1.5em{\txx#1\hss}}\boxline \scratchbox #1\par
+ }
+}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The result is:
+
+\startlinecorrection
+ {\forgetall \getbuffer}
+\stoplinecorrection
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/about/about-titlepage.tex b/Master/texmf-dist/doc/context/sources/general/manuals/about/about-titlepage.tex
index 392fdb1beb0..6ca09955443 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/about/about-titlepage.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/about/about-titlepage.tex
@@ -16,9 +16,9 @@
fill Page enlarged 5mm withcolor \MPcolor{maincolor} ;
- draw anchored.lrt(image(draw textext("\getvariable{document}{title}") xsized(.750PaperWidth) withcolor white),(lrcorner Page) shifted (-PaperWidth/20, PaperWidth/ 5)) ;
- draw anchored.lrt(image(draw textext("\getvariable{document}{subtitle}") xsized(.750PaperWidth) withcolor white),(lrcorner Page) shifted (-PaperWidth/20, PaperWidth/10)) ;
- draw anchored.urt(image(draw textext("\getvariable{document}{author}") xsized(.375PaperWidth) rotated 90 withcolor white),(urcorner Page) shifted (-PaperWidth/20,-PaperWidth/20)) ;
+ draw anchored.lrt(image(draw textext("\documentvariable{title}") xsized(.750PaperWidth) withcolor white),(lrcorner Page) shifted (-PaperWidth/20, PaperWidth/ 5)) ;
+ draw anchored.lrt(image(draw textext("\documentvariable{subtitle}") xsized(.750PaperWidth) withcolor white),(lrcorner Page) shifted (-PaperWidth/20, PaperWidth/10)) ;
+ draw anchored.urt(image(draw textext("\documentvariable{author}") xsized(.375PaperWidth) rotated 90 withcolor white),(urcorner Page) shifted (-PaperWidth/20,-PaperWidth/20)) ;
setbounds currentpicture to Page ;
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-introduction.tex b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-introduction.tex
index 82fcb800707..a1a74cde459 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-introduction.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-introduction.tex
@@ -26,6 +26,67 @@ that is available at the \TEX\ end, or you can use \LUA\ code to do the work, or
you can use a combination. So, from now on, in \CONTEXT\ you can code your style
and document source in (a mixture of) \TEX, \XML, \METAPOST\ and in \LUA.
+% \CONTEXT\ being a \TEX\ macro package quite some action happens at the \TEX\ end;
+% although we do a lot in \LUA, there is no need to abandon the macro language. If
+% I wanted a typesetting system written in procedural language I'd already come up
+% with one but I have no need for it and \TEX\ is more fun anyway. But the fact
+% that we mix these conceptual different languages means that we need ways to
+% communicate between them. The possibilities to communicate and switch between
+% \TEX, \LUA, and of course \METAPOST\ have evolved over time. It started with just
+% \type {\directlua} but we now can use tokens scanners that permit nice
+% interfaces. So, as a consequence the interfaces in \CONTEXT\ also evolved,
+% although mostly deep down out of sight of users: \CONTEXT\ always tries to offer
+% abstract interfaces that as designed in a way that permits upward compatible
+% upgrades.
+
+% Going from \LUA\ to \TEX\ is mostly done with the \type {context} command. The
+% most low level approach would be to use the \type {tex.print} functions but using
+% the \type {context} interface is often better. Going from \TEX\ to \LUA\ is done
+% with \type {\ctxlua} and friends, btu again, you can decide to go low level with
+% \type {\directlua}. Indeed, there is no need to use these interfaces and quite
+% often we see users use low level calls in combination with macros that pass
+% arguments and there's nothing wrong with that. We see no reason to block or
+% overload them.
+
+% In these internet times it is no problem to find comments on code and coding
+% practices (of course not seldom by people who themselves produce code that
+% deserves a lot of comment but get away with it). The same is true for complaints
+% about bugs that not always are put in the perspective of the total amount of well
+% working code or experiments; on the average \TEX\ systems behave quite well and
+% have not that many bugs, but some low level features they can be confusing. We
+% don't impose a coding style in user files but we do so in the core, but that only
+% hampers ourselves.
+
+% Another issue is complaints about manuals or lack of documentation, again, often
+% by people who themselves never produced something that those who they complain
+% about can use, but, that said, lack of documentation has the benefit that one can
+% learn by playing around. There are plenty of examples to learn from, also in the
+% over ten thousand pages of \CONTEXT\ documentation and articles. And of course
+% there is the test suite which has examples. Some users even like to look into the
+% source code to learn some tricks. Now, the internet is not always the friendly
+% and tolerant environment that its marketing suggests and one can run into
+% patronizing comments on how to do thing, but: we don't (and cannot) enforce best
+% practices.
+
+% However, when you define \LUA\ functions you should {\em not} overload existing
+% functions without knowing what you deal with, simply because the whole \CONTEXT\
+% ecosystem could be affected. Don't expect support when you do so. The same is
+% true for \TEX\ macros and even more so for primitives. Although there is some
+% protection going on we think the system should be as open as possible, so little
+% is hidden for the user. \footnote {In the core code and modules that come with
+% \CONTEXT\ we are rather rigourous. There we have patterns that need to be
+% followed. Hacking around and patching at will is not an option there. In the
+% rather open system that a macro package provides it is no problem to quickly mess
+% up the lot with bad code.}
+
+% The reason for mentioning this is that we do see users come up with (often
+% surprising) solutions and we invite them to keep playing around, even with low
+% level code. When writing a document, playing around can be a nice distraction.
+% But, using a high level interface has some benefits too. It gives a bit of
+% protection against bad interactions with other code. It also often involves less
+% coding. Performance might be better although that is not always a real issue as
+% there are plenty of ways to make a \TEX\ system slow anyway.
+
In the following chapters I will introduce typesetting in \LUA, but as we rely on
\CONTEXT\ it is unavoidable that some regular \CONTEXT\ code shows up. The fact
that you can ignore backslashes does not mean that you can do without knowledge
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-luafunctions.tex b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-luafunctions.tex
index b2760e05b3d..c48b852fb93 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-luafunctions.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-luafunctions.tex
@@ -2306,20 +2306,22 @@ one provided by \LUATEX\ as it is more precise:
os.gettimeofday()
\stoptyping
-There is also a more extensive variant:
-
-\starttyping
-os.times()
-\stoptyping
-
-This one is platform dependent and returns a table with \type {utime} (use time),
-\type {stime} (system time), \type {cutime} (children user time), and \type
-{cstime} (children system time).
+% % This one is gone in luametatex:
+%
+% There is also a more extensive variant:
+%
+% \starttyping
+% os.times()
+% \stoptyping
+%
+% This one is platform dependent and returns a table with \type {utime} (use time),
+% \type {stime} (system time), \type {cutime} (children user time), and \type
+% {cstime} (children system time).
\stopsummary
\ShowLuaExampleThree {os} {gettimeofday} {}
-\ShowLuaExampleTwo {os} {times} {}
+%ShowLuaExampleTwo {os} {times} {}
\startsummary[title={runtime}]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-macros.tex b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-macros.tex
index a177db9f87e..7b6f578e754 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-macros.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-macros.tex
@@ -128,9 +128,9 @@ local function startmore(opt_1)
context.startnarrower()
end
-local function stopmore(opt_1)
+local function stopmore()
context.stopnarrower()
- context("stop more, options: %s",interfaces.tolist(opt_1))
+ context("stop more")
context.stopnarrower()
end
@@ -175,7 +175,7 @@ If needed you can access the body of a macro. Take for instance:
\typebuffer \getbuffer
-The following example demonsttaies how we can look inside these macros. You need
+The following example demonstrates how we can look inside these macros. You need
to be aware of the fact that the whole blob of \LUA\ codes is finished before we
return to \TEX, so when we pipe the meaning of \type {TestB} back to \TEX\ it
only gets expanded afterwards. We can use a function to get back to \LUA. It's
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-mkiv.tex
index 5c35fa4e714..9267732fa3a 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-mkiv.tex
@@ -74,6 +74,8 @@
\component cld-logging
\component cld-luafunctions
\component cld-ctxfunctions
+ \component cld-scanners
+ \component cld-variables
\component cld-callbacks
\component cld-backendcode
\component cld-goodies
@@ -84,8 +86,8 @@
\component cld-files
\stopbodymatter
-% \startbackmatter
-% \component cld-index
-% \stopbackmatter
+\startbackmatter
+ \component cld-index
+\stopbackmatter
\stopproduct
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-scanners.tex b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-scanners.tex
new file mode 100644
index 00000000000..3bf5f658d45
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-scanners.tex
@@ -0,0 +1,1048 @@
+% language=uk
+
+\startcomponent cld-ctxscanners
+
+\environment cld-environment
+
+\startchapter[title={Scanners}]
+
+\startsection[title={Introduction}]
+
+\index {implementors}
+\index {scanners}
+
+Here we discuss methods to define macros that directly interface with the \LUA\
+side. It involves all kind of scanners. There are actually more than we discuss
+here but some are meant for low level usage. What is describe here has been used
+for ages and works quite well.
+
+{\em We don't discuss some of the more obscure options here. Some are there just
+because we need them as part of bootstrapping or initializing code and are of no
+real use to users.}
+
+\stopsection
+
+\startsection[title={A teaser first}]
+
+Most of this chapter is examples and you learn \TEX\ (and \LUA) best by just
+playing around. The nice thing about \TEX\ is that it's all about visual output,
+so that's why in the next examples we just typeset some of what we just scanned.
+Of course in practice the \type {actions} will be more complex.
+
+\unexpanded\def\showmeaning#1%
+ {\begingroup
+ \dontleavehmode
+ \ttbf\string #1\space
+ \tttf\meaning#1%
+ \endgroup}
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroA",
+ public = true,
+ arguments = "string",
+ actions = function(s)
+ context("(%s)",s)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\startbuffer[usage]
+\MyMacroA{123}
+\MyMacroA{abc}
+\edef\temp{\MyMacroA{abc}}
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+By default a macro gets defined in the \type {\clf_} namespace but the \type
+{public} option makes it visible. This default indicates that it is actually a
+low level mechanism in origin. More often than not these interfaces are used like
+this:
+
+\starttyping
+\def\MyMacro#1{... \clf_MyMacroA{#1} ...}
+\stoptyping
+
+When we look at the meaning of \type {\MyMacroA} we get:
+
+\blank \showmeaning\MyMacroA \blank
+
+And when we apply this macro as:
+
+\typebuffer[usage]
+
+We get
+
+\blank \getbuffer[usage] \blank
+
+The meaning of \type {\temp} is:
+
+\blank \showmeaning\temp \blank
+
+We can also define the macro to be protected (\type {\unexpanded}) in \CONTEXT\
+speak). We can overload existing scanners but unless we specify the \type
+{overload} option, we get a warning on the console.
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroA",
+ public = true,
+-- overload = true,
+ protected = true,
+ arguments = "string",
+ actions = function(s)
+ context("[%s]",s)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+This time we get:
+
+\getbuffer[usage]
+
+The meaning of \type {\temp} is:
+
+\blank \showmeaning\temp \blank
+
+\stopsection
+
+\startsection[title={Basic data types}]
+
+\index {implementors+arguments}
+
+It is actually possible to write very advanced scanners but unless you're in for
+obscurity the limited subset discussed here is normally enough. The \CONTEXT\
+user interface is rather predictable, unless you want to show off with weird
+additional interfaces, for instance by using delimiters other than curly braces
+and brackets, or by using separators other than commas.
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroB",
+ public = true,
+ arguments = { "string", "integer", "boolean", "dimen" },
+ actions = function(s,i,b,d)
+ context("<%s> <%i> <%l> <%p>",s,i,b,d)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+This time we grab four arguments, each of a different type:
+
+\startbuffer[usage]
+\MyMacroB{foo} 123 true 45.67pt
+
+\def\temp {oof}
+\scratchcounter 321
+\scratchdimen 76.54pt
+
+\MyMacroB\temp \scratchcounter false \scratchdimen
+\stopbuffer
+
+\typebuffer[usage]
+
+The above usage gives:
+
+\getbuffer[usage]
+
+As you can see, registers can be used as well, and the \type {\temp} macro is
+also accepted as argument. The integer and dimen arguments scan standard \TEX\
+values. If you want a \LUA\ number you can specify that as well. As our first
+example showed, when there is one argument you don't need an array to specify
+it.
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroC",
+ public = true,
+ arguments = "number",
+ actions = function(f)
+ context("<%.2f>",f)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroC 1.23
+\MyMacroC 1.23E4
+\MyMacroC -1.23E4
+\MyMacroC 0x1234
+\stopbuffer
+
+As you can see, hexadecimal numbers are also accepted:
+
+\typebuffer[usage]
+
+The above usage gives:
+
+\getbuffer[usage]
+
+\stopsection
+
+\startsection[title={Tables}]
+
+\index {implementors+tables}
+
+A list can be grabbed too. The individual items are separated by spaces and
+items can be bound by braces.
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroD",
+ public = true,
+ arguments = "list",
+ actions = function(t)
+ context("< % + t >",t)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroD { 1 2 3 4 {5 6} }
+\stopbuffer
+
+The macro call:
+
+\typebuffer[usage]
+
+results in:
+
+\getbuffer[usage]
+
+Often in \LUA\ scripts tables are uses all over the place. Picking up a table is
+also supported by the implementer.
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroE",
+ public = true,
+ arguments = {
+ {
+ { "bar", "integer" },
+ { "foo", "dimen" },
+ }
+ },
+ actions = function(t)
+ context("<foo : %p> <bar : %i>",t.foo,t.bar)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroE {
+ foo 12pt
+ bar 34
+}
+\stopbuffer
+
+Watch out, we don't use equal signs and commas here:
+
+\typebuffer[usage]
+
+We get:
+
+\getbuffer[usage]
+
+All the above can be combined:
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroF",
+ public = true,
+ arguments = {
+ "string",
+ {
+ { "bar", "integer" },
+ { "foo", "dimen" },
+ },
+ {
+ { "one", "string" },
+ { "two", "string" },
+ },
+ },
+ actions = function(s,t1,t2)
+ context("<%s> <%p> <%i> <%s> <%s>",s,t1.foo,t1.bar,t2.one,t2.two)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroF
+ {oeps}
+ { foo 12pt bar 34 }
+ { one {x} two {y} }
+\stopbuffer
+
+The following call:
+
+\typebuffer[usage]
+
+Results in one string and two table arguments.
+
+\getbuffer[usage]
+
+You can nest tables, as in:
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroG",
+ public = true,
+ arguments = {
+ "string",
+ "string",
+ {
+ { "data", "string" },
+ { "tab", "string" },
+ { "method", "string" },
+ { "foo", {
+ { "method", "integer" },
+ { "compact", "number" },
+ { "nature" },
+ { "*" }, -- any key
+ } },
+ { "compact", "string", "tonumber" },
+ { "nature", "boolean" },
+ { "escape" },
+ },
+ "boolean",
+ },
+ actions = function(s1, s2, t, b)
+ context("<%s> <%s>",s1,s2)
+ context("<%s> <%s> <%s>",t.data,t.tab,t.compact)
+ context("<%i> <%s> <%s>",t.foo.method,t.foo.nature,t.foo.whatever)
+ context("<%l>",b)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroG
+ {s1}
+ {s2}
+ {
+ data {d}
+ tab {t}
+ compact {12.34}
+ foo { method 1 nature {n} whatever {w} }
+ }
+ true
+\relax
+\stopbuffer
+
+Although the \type {\relax} is not really needed in the next calls, I often use
+it to indicate that we're done:
+
+\typebuffer[usage]
+
+This typesets:
+
+\getbuffer[usage]
+
+\stopsection
+
+\startsection[title=Expansion]
+
+\index {implementors+expansion}
+
+When working with scanners it is important to realize that we have to do with an
+expansion engine. When \TEX\ picks up a token, it can be done as-is, that is the
+raw token, but it can also expand that token first (which can be recursive) and
+then pick up the first token that results from that. Sometimes you want that
+expansion, for instance when you pick up keywords, sometimes you don't.
+
+Expansion effects are most noticeable when we pickup a \quote {string} kind of
+value. In the implementor we have two methods for that: \type {string} and \type
+{argument}. The argument method has an expandable form (the default) and one
+that doesn't expand. Take this:
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroH",
+ public = true,
+ arguments = {
+ "string",
+ "argument",
+ "argumentasis",
+ },
+ actions = function(a,b,c)
+ context.type(a or "-") context.quad()
+ context.type(b or "-") context.quad()
+ context.type(c or "-") context.crlf()
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+Now take this input:
+
+\startbuffer[usage]
+\def\a{A} \def\b{B} \def\c{C}
+\MyMacroH{a}{b}{c}
+\MyMacroH{a\a}{b\b}{c\c}
+\MyMacroH\a\b\c\relax
+\MyMacroH\a xx\relax
+\stopbuffer
+
+\typebuffer[usage]
+
+We we use the string method we need a \type {\relax} (or some spacer) to end
+scanning of the string when we don't use curly braces. The last line is
+actually kind of tricky because the macro expects two arguments after
+scanning the first string.
+
+\blank {\getbuffer[usage]} \blank
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroI",
+ public = true,
+ arguments = {
+ "argument",
+ "argumentasis",
+ },
+ actions = function(a,b,c)
+ context.type(a or "-") context.quad()
+ context.type(b or "-") context.quad()
+ context.type(c or "-") context.crlf()
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+Here is a variant:
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\def\a{A} \def\b{B}
+\MyMacroI{a}{b}
+\MyMacroI{a\a}{b\b}
+\MyMacroI\a\b\relax
+\stopbuffer
+
+With:
+
+\typebuffer[usage]
+
+we get:
+
+\blank {\getbuffer[usage]} \blank
+
+\stopsection
+
+\startsection[title=Boxes]
+
+\index {implementors+boxes}
+
+You can pick up a box too. The value returned is a list node:
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroJ",
+ public = true,
+ arguments = "box",
+ actions = function(b)
+ context(b)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+The usual box specifiers are supported:
+
+\startbuffer[usage]
+\MyMacroJ \hbox {\strut Test 1}
+\MyMacroJ \hbox to 4cm {\strut Test 2}
+\stopbuffer
+
+So, with:
+
+\typebuffer[usage]
+
+we get:
+
+\blank {\forgetall\dontcomplain\getbuffer[usage]} \blank
+
+There are three variants that don't need the box operator \type {hbox}, \type
+{vbox} and \type {vtop}:
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroL",
+ public = true,
+ arguments = {
+ "hbox",
+ "vbox",
+ },
+ actions = function(h,v)
+ context(h)
+ context(v)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+Again, the usual box specifiers are supported:
+
+\startbuffer[usage]
+\MyMacroL {\strut Test 1h} to 10mm {\vfill Test 1v\vfill}
+\MyMacroL spread 1cm {\strut Test 2h} to 15mm {\vfill Test 2v\vfill}
+\stopbuffer
+
+This:
+
+\typebuffer[usage]
+
+gives:
+
+\blank {\forgetall\dontcomplain\showboxes \getbuffer[usage]} \blank
+
+\stopsection
+
+\startsection[title=Like \CONTEXT]
+
+\index {implementors+hashes}
+\index {implementors+arrays}
+
+The previously discussed scanners don't use equal signs and commas as separators,
+but you can enforce that regime in the following way:
+
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroN",
+ public = true,
+ arguments = {
+ "hash",
+ "array",
+ },
+ actions = function(h, a)
+ context.totable(h)
+ context.quad()
+ context.totable(a)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroN
+ [ a = 1, b = 2 ]
+ [ 3, 4, 5, {6 7} ]
+\stopbuffer
+
+This:
+
+\typebuffer[usage]
+
+gives:
+
+\blank {\getbuffer[usage]} \blank
+
+\stopsection
+
+\startsection[title=Verbatim]
+
+\index {implementors+verbatim}
+
+There are a couple of rarely used scanners (there are more of course but these
+are pretty low level and not really used directly using implementors).
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroO",
+ public = true,
+ arguments = "verbatim",
+ actions = function(v)
+ context.type(v)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroO{this is \something verbatim}
+\stopbuffer
+
+There is no expansion applied in:
+
+\typebuffer[usage]
+
+so we get what we input:
+
+\blank {\getbuffer[usage]} \blank
+
+\stopsection
+
+\startsection[title=Macros]
+
+\index {implementors+macros}
+
+We can pick up a control sequence without bothering what it actually
+represents:
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroP",
+ public = true,
+ arguments = "csname",
+ actions = function(c)
+ context("{\\ttbf name:} {\\tttf %s}",c)
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroP\framed
+\stopbuffer
+
+The next control sequence is picked up and its name without the leading
+escape character is returned:
+
+\typebuffer[usage]
+
+So here we get:
+
+\blank {\getbuffer[usage]} \blank
+
+\stopsection
+
+\startsection[title={Token lists}]
+
+\index {implementors+token lists}
+
+If you have no clue what tokens are in the perspective of \TEX, you can skip this
+section. We can grab a token list in two ways. The most \LUA ish way is to grab
+it as a table:
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroQ",
+ public = true,
+ arguments = "toks",
+ actions = function(t)
+ context("%S : ",t)
+ context.sprint(t)
+ context.crlf()
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroQ{this is a {\bf token} list}
+\MyMacroQ{this is a \inframed{token} list}
+\stopbuffer
+
+\typebuffer[usage]
+
+The above sample code gives us:
+
+\blank {\getbuffer[usage]} \blank
+
+An alternative is to keep the list a user data object:
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroR",
+ public = true,
+ arguments = "tokenlist",
+ actions = function(t)
+ context("%S : ",t)
+ context.sprint(t)
+ context.crlf()
+ end,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroR{this is a {\bf token} list}
+\MyMacroR{this is a \inframed{token} list}
+\stopbuffer
+
+\typebuffer[usage]
+
+Now we get:
+
+\blank {\getbuffer[usage]} \blank
+
+\stopsection
+
+\startsection[title={Actions}]
+
+\index {implementors+actions}
+
+The plural \type {actions} suggests that there can be more than one and indeed
+that is the case. The next example shows a sequence of actions that are applied.
+The first one gets the arguments passes.
+
+\startbuffer[definition]
+\startluacode
+ interfaces.implement {
+ name = "MyMacroS",
+ public = true,
+ arguments = "string",
+ actions = { characters.upper, context },
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+\startbuffer[usage]
+\MyMacroS{uppercase}
+\stopbuffer
+
+\typebuffer[usage]
+
+Gives: \inlinebuffer[usage]
+
+You can pass default arguments too. That way you can have multiple macros using
+the same action. Here's how to do that:
+
+\startbuffer[definition]
+\startluacode
+ local function MyMacro(a,b,sign)
+ if sign then
+ context("$%i + %i = %i$",a,b,a+b)
+ else
+ context("$%i - %i = %i$",a,b,a-b)
+ end
+ end
+
+ interfaces.implement {
+ name = "MyMacroPlus",
+ public = true,
+ arguments = { "integer", "integer", true },
+ actions = MyMacro,
+ }
+
+ interfaces.implement {
+ name = "MyMacroMinus",
+ public = true,
+ arguments = { "integer", "integer", false },
+ actions = MyMacro,
+ }
+\stopluacode
+\stopbuffer
+
+\typebuffer[definition] \getbuffer[definition]
+
+So,
+
+\startbuffer[usage]
+\MyMacroPlus 654 321 \crlf
+\MyMacroMinus 654 321 \crlf
+\stopbuffer
+
+\typebuffer[usage]
+
+Gives:
+
+\getbuffer[usage]
+
+If you need to pass a string, you pass it as \type {"'preset'"}, so single quotes
+inside the double ones. Otherwise strings are interpreted as scanner types.
+
+\stopsection
+
+\startsection[title={Embedded \LUA\ code}]
+
+When you mix \TEX\ and \LUA, you can put the \LUA\ code in a \TEX\ file, for
+instance a style. In the previous sections we used this approach:
+
+\starttyping
+\startluacode
+ -- lua code
+\stopluacode
+\stoptyping
+
+This method is both reliable and efficient but you need to keep into mind that
+macros get expanded. In the next code, the second line will give an error when
+you have not defined \type {\foo} as expandable macro. When it is unexpandable it
+will get passed as it is and \LUA\ will see a \type {\f} as an escaped character.
+So, when you want a macro be passes as macro, you need to do it as in the third
+line. The fact that there is a comment trigger (\type {--}) doesn't help here.
+
+\starttyping
+\startluacode
+ context("foo")
+ -- context("\foo")
+ context("\\bar")
+\stopluacode
+\stoptyping
+
+When you use \type {\ctxlua} the same is true but there you also need to keep an
+eye on special characters. For instance a percent sign is then interpreted in the
+\TEX\ way and because all becomes one line, a \type {--} somewhere in the middle
+will make the rest of the line comment:
+
+\starttyping
+\ctxlua {
+ context("foo")
+ % context("\foo")
+ -- context("\\bar")
+}
+\stoptyping
+
+Here, the second line goes away (\TEX\ comment) and the third line obscures all
+that follows. You can use \type {\letterpercent} to smuggle a percent sign in a
+\type {\ctxlua} call. Special characters like a hash symbol also need to be
+passed by name. Normally curly braces are no problem because \LUA\ also likes
+them properly nested.
+
+When things become too messy and complex you can always put the code in an
+external file and load that one (e.g. with \type {require}.
+
+In the examples in this chapter we put the function in the table, but for long
+ones you might want to do this:
+
+\starttyping
+\startluacode
+ local function MyMacro(s)
+ -- lots of code
+ end
+
+ interfaces.implement {
+ name = "MyMacro",
+ public = true,
+ arguments = "string",
+ actions = MyMacro,
+ }
+\stopluacode
+\stoptyping
+
+It is a common mistake not to define variables and functions as local. If you
+define them global for sure there will become a time when this bites you.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
+
+% conditional : true|false|0=true|!0=false : too weird for users
+% bracketed : maybe, but first I need a use case
+% bracketedasis : maybe, but first I need a use case
+% optional : maybe, but first I need a use case
+
+\startluacode
+
+ local function Grabbed(t)
+ context(t)
+ end
+
+ interfaces.implement {
+ name = "GrabC",
+ public = true,
+ actions = Grabbed,
+ arguments = "bracketed",
+ }
+ interfaces.implement {
+ name = "GrabD",
+ public = true,
+ actions = Grabbed,
+ arguments = "bracketedasis",
+ }
+ interfaces.implement {
+ name = "GrabE",
+ public = true,
+ actions = Grabbed,
+ arguments = "optional",
+ }
+\stopluacode
+
+\GrabC [foo {\red okay C} bar] \par
+\GrabC \par
+\GrabD [foo {\red okay D} bar] \par
+\GrabE [foo {\red okay E} bar] \par
+\GrabE \par
+
+% once stable:
+
+\startluacode
+ local random = math.random
+ local randomseed = math.randomseed
+
+ local scan_word = tokens.scanners.word
+ local scan_integer = tokens.scanners.integer
+ local scan_dimen = tokens.scanners.dimen
+ local scan_number = tokens.scanners.float
+
+ local scan_integer = tokens.scanners.luainteger
+ local scan_cardinal = tokens.scanners.luacardinal
+ local scan_number = tokens.scanners.luanumber
+
+ local I = 0
+ local D = 0
+ local F = 0
+
+ interfaces.implement {
+ name = "TestInteger",
+ public = true,
+ actions = function(b) if b then return I else I = scan_integer() end end,
+ valuetype = "count",
+ }
+
+ interfaces.implement {
+ name = "TestDimension",
+ public = true,
+ actions = function(b) if b then return D else D = scan_dimen() end end,
+ valuetype = "dimen",
+ }
+
+ interfaces.implement {
+ name = "TestFloat",
+ public = true,
+ actions = function(b)
+ if b then
+ context("%q",F)
+ else
+ F = scan_number()
+ end
+ end,
+ valuetype = "none",
+ }
+
+ interfaces.implement {
+ name = "TestThis",
+ public = true,
+ actions = function(b)
+ if b then
+ return random(scan_integer(),scan_integer())
+ else
+ randomseed(scan_integer(true))
+ end
+ end,
+ valuetype = "count",
+ }
+
+\stopluacode
+
+{\tttf [set:\TestInteger 808714][get: \the\TestInteger ]}\par % [get: \number\TestInteger ]}\par
+{\tttf [set:\TestDimension 12.34pt][get: \the\TestDimension]}\par % [get: \number\TestDimension]}\par
+{\tttf [set:\TestFloat 12.34567890e99][get: \the\TestFloat ]}\par % [get: \number\TestFloat ]}\par
+
+{\tttf \TestThis 123 \dorecurse{10}{\the \TestThis 1 10 \space}}\par
+{\tttf \TestThis 123 \dorecurse{10}{\the \TestThis 1 10 \space}}\par
+{\tttf \TestThis 456 \dorecurse{10}{\the \TestThis 1 10 \space}}\par
+{\tttf \dorecurse{10}{\the \TestThis 1 10 \space}}\par
+
+\TestFloat .1e20\relax
+\TestFloat -0x1.693d8e8943f17p+332\relax
+\TestFloat 0x1.693d8e8943f17p+332\relax
+
+\TestFloat 123.345E67\relax
+
+{\tttf [\the\TestFloat]}
+
+% maybe some day:
+
+% \startluacode
+% local t1 = token.get_next()
+% local t2 = token.get_next()
+% local t3 = token.get_next()
+% local t4 = token.get_next()
+% -- watch out, we flush in sequence
+% token.put_next { t1, t2 }
+% -- but this one gets pushed in front
+% token.put_next ( t3, t4 )
+% \stopluacode
+% abcd
+
+% \ctxlua{whatever = { } whatever.bf = token.get_next()}\bf
+
+\startluacode
+ local t_bf = whatever and whatever.bf or token.create("bf")
+ local put = token.put_next
+
+ interfaces.implement {
+ name = "whateverbfone",
+ public = true,
+ actions = function()
+ put(t_bf)
+ end
+ }
+
+ local ctx_whateverbfxxx = context.whateverbfxxx
+
+ interfaces.implement {
+ name = "whateverbftwo",
+ public = true,
+ actions = function()
+ ctx_whateverbfxxx(false)
+ end
+ }
+
+ interfaces.implement {
+ name = "whateverbfthree",
+ public = true,
+ actions = context.core.cs.whateverbfxxx
+ }
+
+\stopluacode
+
+\let\whateverbfxxx\bf
+
+\dontleavehmode{xxx: \whateverbfxxx xxx}\quad
+\dontleavehmode{one: \whateverbfone one}\quad
+\dontleavehmode{two: \whateverbftwo two}\quad
+\dontleavehmode{two: \whateverbfthree three}\par
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-specialcommands.tex b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-specialcommands.tex
index 37ecf45c684..510c820f9e5 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-specialcommands.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-specialcommands.tex
@@ -237,14 +237,14 @@ context.stepwise(function()
end)
\stopluacode
\stoptext
-\starttyping
+\stoptyping
Instead of the \type {testpage} function you can also play directly with
registers, like:
\starttyping
if tex.pagegtotal + tex.count.lineheight > tex.pagetotal then
-\starttyping
+\stoptyping
but often an already defined helper does a better job. Of course you will
probably never need this kind of hacks anyway, if only because much more is going
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-variables.tex b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-variables.tex
new file mode 100644
index 00000000000..c9afbd44c0b
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-variables.tex
@@ -0,0 +1,340 @@
+% language=uk
+
+\startcomponent cld-variables
+
+\environment cld-environment
+
+\startchapter[title={Variables}]
+
+\startsection[title={Introduction}]
+
+\index {variables}
+
+Sometimes a bit of experimenting and exploring the boundaries of the \TEX|-|\LUA\
+interfaces results in new mechanisms. To what extent they are really useful is
+hard to say but we just keep them around. Some are described here. This is, at
+least for the moment, a \LMTX\ specific chapter.
+
+\stopsection
+
+\startsection[title={Simple tables}]
+
+\index {variables+grouped tables}
+
+The basic \TEX\ data types are counters (integers), dimensions (kind of floating
+point variables with typographic dimensions), token lists, node lists (boxes),
+fonts, and so on, but no data organized in tables. The first mechanism that we
+discuss is one that obeys grouping. In that respect is behaves like regular
+registers.
+
+\startbuffer
+\newhashedtable\somehashtable
+
+\somehashtable{ foo = 123, bar = "foo" }
+[123 = \the\somehashtable{foo}]
+[foo = \the\somehashtable{bar}]
+
+\bgroup
+\somehashtable{ foo = 456, bar = "oof" }
+[456 = \the\somehashtable{foo}]
+[oof = \the\somehashtable{bar}]
+\egroup
+
+[123 = \the\somehashtable{foo}]
+[foo = \the\somehashtable{bar}]
+
+\bgroup
+\global\somehashtable{ foo = 456 }
+ \somehashtable{ bar = "oof" }
+[456 = \the\somehashtable{foo}]
+[oof = \the\somehashtable{bar}]
+\egroup
+
+[456 = \the\somehashtable{foo}]
+[foo = \the\somehashtable{bar}]
+\stopbuffer
+
+\typebuffer
+
+We define a hashed table, one with keys and values. The definition is global.
+We can then assign values to this table where the assignments themselves are
+hash tables. The above code generates:
+
+\getbuffer
+
+As you can see, the \type {\global} prefix makes the value persistent outside the
+group. You can mix local and global assignments.
+
+Instead of a hashed table, you can have an indexed table. This time the keys are
+numbers.
+
+\startbuffer
+\newindexedtable\someindextable
+
+\someindextable{ 123, "foo" }
+[123 = \the\someindextable 1]
+[foo = \the\someindextable 2]
+
+\bgroup
+\someindextable{ 456, "oof" }
+[456 = \the\someindextable 1]
+[oof = \the\someindextable 2]
+\egroup
+
+[123 = \the\someindextable 1]
+[foo = \the\someindextable 2]
+
+\bgroup
+\global\someindextable{ [1] = 456 }
+ \someindextable{ [2] = "oof" }
+[456 = \the\someindextable 1]
+[oof = \the\someindextable 2]
+\egroup
+
+[456 = \the\someindextable 1]
+[foo = \the\someindextable 2]
+\stopbuffer
+
+\typebuffer
+
+The outcome is the same as before:
+
+\getbuffer
+
+At the \LUA\ end you can access these tables too:
+
+\startbuffer
+\startluacode
+context("[hashed : bar = %s]",context.hashedtables.somehashtable.bar)
+context("[indexed : 2 = %s]", context.indexedtables.someindextable[2])
+\stopluacode
+\stopbuffer
+
+\typebuffer
+
+Indeed we get:
+
+\getbuffer
+
+\stopsection
+
+\startsection[title={Data tables}]
+
+\index {variables+data tables}
+
+In \LUA, tables can be more complex than in the previous section. When you need
+more complex tables, it is likely that your grouping needs are also different,
+which is why we have another mechanism. This mechanism is build on top of another
+model: data values. There are 64K integer registers in any modern \TEX\ engine
+and normally that is more than enough. However, in addition in \LUAMETATEX\ we
+have a variant integer storage unit, one that is lightweight and where the amount
+is limited by the size of the hash table. It was added as part of the low level
+cleanup up of the \LUA\ token interface (a bit more abstraction). Here is an
+example of its usage:
+
+\startbuffer
+\dorecurse {100} {
+ \setdatavalue{#1}{#1}
+}
+
+\start \tttf \darkred \raggedright \dorecurse {100} {
+ #1=\scratchcounter\getdatavalue{#1}\the\scratchcounter
+} \par \stop \blank
+
+\start \tttf \darkgreen \raggedright \dorecurse {100} {
+ #1=\thedatavalue{#1}%
+} \par \stop \blank
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We define hundred values which are a simple numeric macros. Here we use two
+auxiliary macros because we prefer to use a dedicated namespace for these
+variables. However, there are also primitives that deal with these data values:
+
+\startbuffer[usage]
+\setdatavalue{my-data}{12345}%
+\letdatacode \MyData 67890
+\thedatavalue{my-data} \the\MyData
+\stopbuffer
+
+\typebuffer[usage]
+
+gives: \inlinebuffer[usage]
+
+But, when more is needed than simple integers, tables come into view. This interface
+is different from the simple one and involves more commands. The next examples show
+about all:
+
+\startbuffer
+\newluatable\testtable
+\setluatable\testtable{ foo = 123, bar = "456", oof = "rab" }
+% \inspectluatable\testtable
+\darkcyan
+foo = \getfromluatable\testtable{foo}\par
+bar = \getfromluatable\testtable{bar}\par
+oof = \getfromluatable\testtable{oof}\par
+\bgroup
+ \useluatable\testtable
+ \setluatable\testtable{ foo = 123123, bar = "456456" }
+ % \inspectluatable\testtable
+ \darkmagenta
+ foo = \getfromluatable\testtable{foo}\par
+ bar = \getfromluatable\testtable{bar}\par
+ oof = \getfromluatable\testtable{oof}\par
+ \startluacode
+ local t = context.luatables.get("testtable")
+ context("<%s %s %s>",t.foo,t.bar,t.oof)
+ \stopluacode \par
+\egroup
+\darkyellow
+foo = \getfromluatable\testtable{foo}\par
+bar = \getfromluatable\testtable{bar}\par
+oof = \getfromluatable\testtable{oof}\par
+\startluacode
+ local t = context.luatables.get("testtable")
+ context("<%s %s %s>",t.foo,t.bar,t.oof)
+\stopluacode \par
+% \inspectluatable\testtable
+\stopbuffer
+
+\typebuffer
+
+The tables are semi|-|local: \type {\newluatable} creates a table and \type
+{\useluatable} will create a local copy that is discarded when the group ends.
+
+\startpacked
+\tttf \getbuffer
+\stoppacked
+
+Hashed and indexed tables can be used mixed, but there are additional accessors
+for indexed tables because there we expect numbers.
+
+\startbuffer
+\newluatable\moretable
+\setluatable\moretable{ 1, "foo" }
+\darkcyan
+[1] = \getfromluatable\moretable{1}\par
+[2] = \idxfromluatable\moretable 2 \par
+\bgroup
+ \useluatable\moretable
+ \setluatable\moretable{ foo = 123123, bar = "456456" }
+ \darkmagenta
+ [1] = \getfromluatable\moretable{1}\par
+ [2] = \idxfromluatable\moretable 2 \par
+ \startluacode
+ local t = context.luatables.get("moretable")
+ context("<%s %s>",t[1],t[2])
+ \stopluacode \par
+\egroup
+\darkyellow
+[1] = \getfromluatable\moretable{1}\par
+[2] = \idxfromluatable\moretable 2 \par
+\startluacode
+ local t = context.luatables.get("moretable")
+ context("<%s %s>",t[1],t[2])
+\stopluacode \par
+\stopbuffer
+
+\typebuffer
+
+\startpacked
+\tttf \getbuffer
+\stoppacked
+
+You can create more complex (nested) tables that you can handle at the \LUA\
+end in the usual way. Basically any \LUA\ that makes a table can go between
+the curly braces.
+
+\stopsection
+
+\startsection[title=Named variables]
+
+\index {variables+named}
+\index {variables+integers}
+\index {variables+cardinals}
+\index {variables+floats}
+\index {integers}
+\index {cardinals}
+\index {floats}
+
+Just because it can be done, and maybe it even has it use, we offer additional
+numbers, stored and accessible by name. The different types all live in their
+own namespace:
+
+\startbuffer[definition]
+\luainteger bar 123456
+\luafloat bar 123.456e12
+\luainteger gnu = 0xFFFF
+\stopbuffer
+
+\startbuffer[usage]
+{\darkcyan \the\luainteger bar}
+{\darkmagenta\the\luafloat bar}
+{\darkyellow \the\luainteger gnu}
+\stopbuffer
+
+\typebuffer[definition,usage] \getbuffer[definition]
+
+These serialize like: \getbuffer[usage]\removeunwantedspaces , and when not set they
+default to zero. There is an extra type, cardinal:
+
+\startbuffer
+\luainteger a 0x7FFFFFFFFFFFFFFF
+\luainteger b -0x7FFFFFFFFFFFFFFF
+\luacardinal c 0xFFFFFFFFFFFFFFFF
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We cheat a bit behind the screens because it is actually a double but we scan
+it as positive integer and serialize it as such.
+
+\startbuffer
+[\the \luainteger a\relax]\par
+[\the \luainteger b\relax]\par
+[\the \luacardinal c\relax]\par
+\stopbuffer
+
+\typebuffer \getbuffer
+
+You have access to the numbers at the \LUA\ end, as in:
+
+\startbuffer
+\luainteger one 123 \luafloat two 456.678
+\luaexpr{interfaces.numbers.one/1000 + interfaces.numbers.two/10000}
+\stopbuffer
+
+\typebuffer
+
+There are \type {integers}, \type {cardinals} and \type {floats} but the \type
+{numbers} one is the most generic as it tries to resolve it from one of these
+namespaces, so we get: [\inlinebuffer\space\space]. There is also a related
+expression command:
+
+\startbuffer
+(?: \luaexpression {n.one/1000 + n.two/10000})
+(f: \luaexpression float {n.one/1000 + n.two/10000})
+(i: \luaexpression integer {n.one/1000 + n.two/10000})
+(c: \luaexpression cardinal {n.one/1000 + n.two/10000})
+(l: \luaexpression lua {n.one/1000 + n.two/10000})
+\stopbuffer
+
+\typebuffer
+
+It typesets this (watch the \type {lua} variant, which is a precise
+roundtrip serialization method):
+
+\startlines
+\tttf \getbuffer
+\stoplines
+
+The \type {n} table is just a shortcut to \type {interfaces.numbers}.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-keywords.tex b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-keywords.tex
new file mode 100644
index 00000000000..1ffacf0ab51
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-keywords.tex
@@ -0,0 +1,395 @@
+% language=us
+
+% Talking of keywords: Jacob Collier, Count The People is definitely an example
+% of showing keywords and no way that the fonts used there are done by tex:
+%
+% https://www.youtube.com/watch?v=icplHV25fqs
+
+\environment evenmore-style
+
+\startcomponent evenmore-keywords
+
+\startchapter[title=Keywords]
+
+Some primitives in \TEX\ can take one or more optional keywords and|/|or keywords
+followed by one or more values. In traditional \TEX\ it concerns a handful of
+primitives, in \PDFTEX\ there are plenty of backend|-|related primitives,
+\LUATEX\ introduced optional keywords to some math constructs and attributes to
+boxes, and \LUAMETATEX\ adds some more too. The keyword scanner in \TEX\ is
+rather special. Keywords are used in cases like:
+
+\starttyping
+\hbox spread 10cm {...}
+\advance\scratchcounter by 10
+\vrule width 3cm height 1ex
+\stoptyping
+
+Sometimes there are multiple keywords, as with rules, in which case you can
+imagine a case like:
+
+\starttyping
+\vrule width 3cm depth 1ex width 10cm depth 0ex height 1ex\relax
+\stoptyping
+
+Here we add a \type {\relax} to end the scanning. If we don't do that and the
+rule specification is followed by arbitrary (read:\ unpredictable) text, the next
+word might be a valid keyword and when followed by a dimension (unlikely) it will
+happily be read as a directive, or when not followed by a dimension an error
+message will show up. Sometimes the scanning is more restricted, as with glue
+where the optional \type {plus} and \type {minus} are to come in that order, but
+when missing, again a word from the text can be picked up if one doesn't
+explicitly end with a \type {\relax} or some other token.
+
+\starttyping
+\scratchskip = 10pt plus 10pt minus 10pt % okay
+\scratchskip = 10pt plus 10pt % okay
+\scratchskip = 10pt minus 10pt % okay
+\scratchskip = 10pt minus 10pt plus 10pt % typesets "plus 10pt"
+\scratchskip = 10pt plus whatever % an error
+\stoptyping
+
+The scanner is case insensitive, so the following specifications are all valid:
+
+\starttyping
+\hbox To 10cm {To}
+\hbox TO 10cm {TO}
+\hbox tO 10cm {tO}
+\hbox to 10cm {to}
+\stoptyping
+
+It happens that keywords are always simple English words so the engine uses a
+cheap check deep down, just offsetting to uppercase, but of course that will not
+work for arbitrary \UTF-8\ (as used in \LUATEX) and it's also unrelated to the
+upper- and lowercase codes as \TEX\ knows them.
+
+The above lines scan for the keyword \type {to} and after that for a dimension.
+While keyword scanning is case tolerant, dimension scanning is period tolerant:
+
+\starttyping
+\hbox to 10cm {10cm}
+\hbox to 10.0cm {10.0cm}
+\hbox to .0cm {.0cm}
+\hbox to .cm {.cm}
+\hbox to 10.cm {10.cm}
+\stoptyping
+
+These are all valid and according to the specification; even the single period is
+okay, although it looks funny. It would not be hard to intercept that but I guess
+that when \TEX\ was written anything that could harm performance was taken into
+account. One can even argue for cases like:
+
+\starttyping
+\hbox to \first.\second cm {.cm}
+\stoptyping
+
+Here \type {\first} and|/|or \type {\second} can be empty. Most users won't
+notice these side effects of scanning numbers anyway.
+
+The reason for writing up any discussion of keywords is the following. Optional
+keyword scanning is kind of costly, not so much now, but more so decades ago
+(which led to some interesting optimizations, as we'll see). For instance, in the
+first line below, there is no keyword. The scanner sees a \type {1} and it not
+being a keyword, pushes that character back in the input.
+
+\starttyping
+\advance\scratchcounter 10
+\advance\scratchcounter by 10
+\stoptyping
+
+In the case of:
+
+\starttyping
+\scratchskip 10pt plux
+\stoptyping
+
+it has to push back the four scanned tokens \type {plux}. Now, in the engine
+there are lots of cases where lookahead happens and when a condition is not
+satisfied, the just|-|read token is pushed back. Incidentally, when picking up
+the next token triggered some expansion, it's not the original next token that
+gets pushed back, but the first token seen after the expansion. Pushing back
+tokens is not that inefficient, although it involves allocating a token and
+pushing and popping input stacks (we're talking of a mix of reading from file,
+token memory, \LUA\ prints, etc.)\ but it always takes a little time and memory.
+In \LUATEX\ there are more keywords for boxes, and there we have loops too: in a
+box specification one or more optional attributes are scanned before the optional
+\type {to} or \type {spread}, so again there can be push back when no more \type
+{attr} are seen.
+
+\starttyping
+\hbox attr 1 98 attr 2 99 to 1cm{...}
+\stoptyping
+
+In \LUAMETATEX\ there is even more optional keyword scanning, but we leave that
+for now and just show one example:
+
+\starttyping
+\hbox spread 10em {\hss
+ \hbox orientation 0 yoffset 1mm to 2em {up}\hss
+ \hbox to 2em {here}\hss
+ \hbox orientation 0 xoffset -1mm to 2em {down}\hss
+}
+\stoptyping
+
+Although one cannot mess too much with these low|-|level scanners there was room
+for some optimization, so the penalty we pay for more keyword scanning in
+\LUAMETATEX\ is not that high. (I try to compensate when adding features that
+have a possible performance hit with some gain elsewhere.)
+
+It will be no surprise that there can be interesting side effects to keyword
+scanning. For instance, using the two character keyword \type {by} in an \type
+{\advance} can be more efficient because nothing needs to be pushed back. The
+same is true for the sometimes optional equal:
+
+\starttyping
+\scratchskip = 10pt
+\stoptyping
+
+Similar impacts on efficiency can be found in the way the end of a number is
+seen, basically anything not resolving to a number (or digit). (For these, assume
+a following token will terminate the number if needed; we're focusing on the
+spaces here.)
+
+\starttyping
+\scratchcounter 10% space not seen, ends \cs
+\scratchcounter =10% no push back of optional =
+\scratchcounter = 10% extra optional space gobble
+\scratchcounter = 10 % efficient ending of number scanning
+\scratchcounter = 10\relax % depending on engine less efficient
+\stoptyping
+
+In the above examples scanning the number involves: skipping over spaces,
+checking for an optional equal, skipping over spaces, scanning for a sign,
+checking for an optional octal or hexadecimal trigger (single or double quote
+character), scanning the number till a non|-|digit is seen. In the case of
+dimensions there is fraction scanning as well as unit scanning too.
+
+In any case, the equal is optional and kind of a keyword. Having an equal can be
+more efficient then not having one, again due to push back in case of no equal
+being seen, In the process spaces have been skipped, so add to the overhead the
+scanning for optional spaces. In \LUAMETATEX\ all that has been optimized a bit.
+By the way, in dimension scanning \type {pt} is actually a keyword and as there
+are several dimensions possible quite some push back can happen there, but we
+scan for the most likely candidates first.
+
+All that said, we're now ready for a surprise. The keyword scanner gets a string
+that it will test for, say, \type {to} in case of a box specification. It then
+will fetch tokens from whatever provides the input. A token encodes a so|-|called
+command and a character and can be related to a control sequence. For instance,
+the character \type {t} becomes a letter command with related value \number`t.
+So, we have three properties: the command code, the character code and the
+control sequence code. Now, instead of checking if the command code is a letter
+or other character (two checks) a fast check happens for the control sequence
+code being zero. If that is the case, the character code is compared. In practice
+that works out well because the characters that make up a keyword are in the
+range \number"41--\number"5A\ and \number"61--\number"7A, and all other character
+codes are either below that (the ones that relate to primitives where the
+character code is actually a subcommand of a limited range) or much larger
+numbers that, for instance, indicate an entry in some array, where the first
+useful index is above the mentioned ranges.
+
+The surprise is in the fact that there is no checking for letters or other
+characters, so this is why the following code will work too: \footnote {No longer
+in \LUAMETATEX\ where we do a bit more robust check.}
+
+\starttyping
+\catcode `O= 1 \hbox tO 10cm {...} % { begingroup
+\catcode `O= 2 \hbox tO 10cm {...} % } endgroup
+\catcode `O= 3 \hbox tO 10cm {...} % $ mathshift
+\catcode `O= 4 \hbox tO 10cm {...} % & alignment
+\catcode `O= 6 \hbox tO 10cm {...} % # parameter
+\catcode `O= 7 \hbox tO 10cm {...} % ^ superscript
+\catcode `O= 8 \hbox tO 10cm {...} % _ subscript
+\catcode `O=11 \hbox tO 10cm {...} % letter
+\catcode `O=12 \hbox tO 10cm {...} % other
+\stoptyping
+
+In the first line, if we changed the catcode of \type {T} (instead of \type {O}),
+it gives an error because \TEX\ sees a begin group character (category code 1)
+and starts the group, but as a second character in a keyword (\type {O}) it's
+okay because \TEX\ will not look at the category code.
+
+Of course only the cases \type {11} and \type {12} make sense in practice.
+Messing with the category codes of regular letters this way will definitely give
+problems with processing normal text. In a case like:
+
+\starttyping
+{\catcode `o=3 \hbox to 10cm {oeps}} % $ mathshift {oeps}
+{\catcode `O=3 \hbox to 10cm {Oeps}} % $ mathshift {$eps}
+\stoptyping
+
+we have several issues: the primitive control sequence \type {\hbox} has an \type
+{o} so \TEX\ will stop after \type {\hb} which can be undefined or a valid macro
+and what happens next is hard to predict. Using uppercase will work but then the
+content of the box is bad because there the \type {O} enters math. Now consider:
+
+\starttyping
+{\catcode `O=3 \hbox tO 10cm {Oeps Oeps}} % {$eps $eps}
+\stoptyping
+
+This will work because there are now two \type {O}'s in the box, so we have
+balanced inline math triggers. But how does one explain that to a user? (Who
+probably doesn't understand where an error message comes from in the first
+place.) Anyway, this kind of tolerance is still not pretty, so in \LUAMETATEX\ we
+now check for the command code and stick to letters and other characters. On
+today's machines (and even on my by now ancient workhorse) the performance hit
+can be neglected.
+
+In fact, by intercepting the weird cases we also avoid an unnecessary case check
+when we fall through the zero control sequence test. Of course that also means
+that the above mentioned category code trickery doesn't work any more: only
+letters and other characters are now valid in keyword scanning. Now, it can be
+that some macro programmer actually used those side effects but apart from some
+macro hacker being hurt because no longer mastering those details can be showed
+off, it is users that we care more for, don't we?
+
+To be sure, the abovementioned performance of keyword and equal scanning is not
+that relevant in practice. But for the record, here are some timings on a laptop
+with a i7-3849\cap{QM} processor using \MINGW\ binaries on a 64-bit \MSWINDOWS\
+10 system. The times are the averages of five times a million such assignments
+and advancements.
+
+\starttabulate[|l|c|c|c|]
+\FL
+\NC one million times \NC terminal \NC \LUAMETATEX\ \NC \LUATEX \NC \NR
+\ML
+\NC \type {\advance\scratchcounter 1} \NC space \NC 0.068 \NC 0.085 \NC \NR
+\NC \type {\advance\scratchcounter 1} \NC \type {\relax} \NC 0.135 \NC 0.149 \NC \NR
+\NC \type {\advance\scratchcounter by 1} \NC space \NC 0.087 \NC 0.099 \NC \NR
+\NC \type {\advance\scratchcounter by 1} \NC \type {\relax} \NC 0.155 \NC 0.161 \NC \NR
+\NC \type {\scratchcounter 1} \NC space \NC 0.057 \NC 0.096 \NC \NR
+\NC \type {\scratchcounter 1} \NC \type {\relax} \NC 0.125 \NC 0.151 \NC \NR
+\NC \type {\scratchcounter=1} \NC space \NC 0.063 \NC 0.080 \NC \NR
+\NC \type {\scratchcounter=1} \NC \type {\relax} \NC 0.131 \NC 0.138 \NC \NR
+\LL
+\stoptabulate
+
+We differentiate here between using a space as terminal or a \type {\relax}. The
+latter is a bit less efficient because more code is involved in resolving the
+meaning of the control sequence (which eventually boils down to nothing) but
+nevertheless, these are not timings that one can lose sleep over, especially when
+the rest of a decent \TEX\ run is taken into account. And yes, \LUAMETATEX\
+(\LMTX) is a bit faster here than \LUATEX, but I would be disappointed if that
+weren't the case.
+
+% luametatex:
+
+% \luaexpr{(0.068+0.070+0.069+0.067+0.068)/5} 0.068\crlf
+% \luaexpr{(0.137+0.132+0.136+0.137+0.134)/5} 0.135\crlf
+% \luaexpr{(0.085+0.088+0.084+0.089+0.087)/5} 0.087\crlf
+% \luaexpr{(0.145+0.160+0.158+0.156+0.154)/5} 0.155\crlf
+% \luaexpr{(0.060+0.055+0.059+0.055+0.056)/5} 0.057\crlf
+% \luaexpr{(0.118+0.127+0.128+0.122+0.130)/5} 0.125\crlf
+% \luaexpr{(0.063+0.062+0.067+0.061+0.063)/5} 0.063\crlf
+% \luaexpr{(0.127+0.128+0.133+0.128+0.140)/5} 0.131\crlf
+
+% luatex:
+
+% \luaexpr{(0.087+0.090+0.083+0.081+0.086)/5} 0.085\crlf
+% \luaexpr{(0.150+0.151+0.146+0.154+0.145)/5} 0.149\crlf
+% \luaexpr{(0.100+0.092+0.113+0.094+0.098)/5} 0.099\crlf
+% \luaexpr{(0.162+0.165+0.161+0.160+0.157)/5} 0.161\crlf
+% \luaexpr{(0.093+0.101+0.086+0.100+0.098)/5} 0.096\crlf
+% \luaexpr{(0.147+0.151+0.160+0.144+0.151)/5} 0.151\crlf
+% \luaexpr{(0.076+0.085+0.088+0.073+0.078)/5} 0.080\crlf
+% \luaexpr{(0.136+0.138+0.142+0.135+0.140)/5} 0.138\crlf
+
+After the \CONTEXT\ 2020 meeting I entered another round of staring at the code.
+One of the decision made at that meeting was to drop the \type {nd} and \type
+{nc} units as they were never official. That made me (again) wonder of that bit
+of the code could be done nicer as there is a mix of scanning units like \type
+{pt}, \type {bp} and \type {cm}, fillers like \type {fi} and \type {fill}, pseudo
+units like \type {ex} and \type {em}, special interception of \type {mu}, as well
+as the \type {plus} and \type {minus} parsing for glue. That code was already
+redone a bit so that here was less push back of tokens which had the side effect
+of dimension scanning being some 50\% faster than in \LUATEX.
+
+The same is true for scanning rule specs and scanning the box properties. In the
+later case part of the optimization came from not checking properties that
+already had been set, or only scanning them when for instance the \type
+{orientation} flag had been set (a new option in \LUAMETATEX\ with an additional
+four offset and move parameters). Also, some options, like the target dimensions,
+came after scanning the new ones. Again, this was quite a bit faster than in
+\LUATEX, not that it is noticeable on a normal run. All is mixed with skipping
+spacers and relax tokens plus quitting at a brace.
+
+Similar mixed scanning happens in some of the (new) math command, but these are
+less critical. Actually there some new commands had to be used because for
+instance \type {\over} takes any character as valid argument and keywords would
+definitely be incompatible there.
+
+Anyway, I started wondering if some could be done differently and finally decided
+to use a method that I already played with years ago. The main reason for not
+using it was that I wanted to remain compatible with the way traditional \TEX\
+scans. However, as we have many more keyword we already are no longer compatible
+in that department and the alternative implementation makes the code look nicer
+and has the benefit of being (more than) twice as fast. And when I run into
+issues in \CONTEXT\ I should just fix sloppy code.
+
+The compatibility issue is not really a problem when you consider the following
+cases.
+
+\starttyping
+\hbox reverse attr 123 456 orientation 4 xoffset 10pt spread 10cm { }
+\hrule xoffset 10pt width 10cm depth 3mm
+\hskip 3pt plus 2pt minus 1pt
+\stoptyping
+
+In the original approach these three case each have their own special side
+effects. In the case of a \type {\hbox} the scanning stops at a relax or left
+brace. An unknown keyword gives an error. So, there is no real benefit in pushing
+back tokens here. The order matters: the \type {spread} or \type {to} comes last.
+
+In the case of a \type {\hrule} the scanning stops when the keyword is not one of
+the known. This has the side effect that when such a rule definition is hidden in
+a macro and followed by for instance \type {width} without unit one gets an error
+and when a unit is given the rule can come out different than expected and the
+text is gone. For that reason a rule specification like this is often closed by
+\type {\relax} (any command that doesn't expand to a keyword works too). Here
+keywords can occur multiple times. As we have additional keyword a lookahead
+becomes even more an issue (not that \type {xoffset}) is a likely candidate.
+
+The last example is special in a different way: order matters in the sense that a
+\type {minus} specifier can follow a \type {plus} but not the reverse. And only
+one \type {plus} and \type {minus} can be given. Again one can best finish this
+specification by a something that doesn't look like a keyword, so often one will
+see a \type {\relax}.
+
+The advantage of the new method is that the order doesn't matter any more and
+that using a keyword multiple times overloads earlier settings. And this is
+consistent for all commands that used keywords (with a few exceptions in math
+where keywords drive later parsing and for font definitions where we need to be
+compatible. We give a slightly better error message: we mention the expected
+keyword. Another side effect is that any characters that is a legal start of a
+known keyword will trigger further parsing and issue an error message when it
+fails. Indeed, \LUAMETATEX\ has no mercy.
+
+In practice the mentioned special effects mean that a macro package will not run
+into trouble with boxes because unknown keywords make it crash and that rules and
+glue is terminated in a way that prevents lookahead. The new method kind of
+assumes this and one can argue that when something breaks one has to fix the
+macro code. Macro writers know that one cannot predict what users come up with
+and that users also don't look into the macros and therefore they take
+precautions. Also, a more rigorous parsing results in hopefully a better message.
+
+And yes, when I ran the test suite there was indeed a case where I had to add a
+\type {\relax}, but I can live with that. As long as users don't notice it.
+
+Now, one of the interesting properties of the slightly different scanning is
+that we can do this:
+
+\starttyping
+\hbox to 4cm attr 123 456 reverse to 3cm {...}
+\stoptyping
+
+So, we have a less strict order and we can overload arguments too. We'll see how
+this will be applied in \CONTEXT.
+
+\stopchapter
+
+\stopcomponent
+
+% another nice example: \the is expanded so we get the old value
+
+% \scratchskip = 10pt plus 1fill \the\scratchskip % old value
+% \scratchskip = 10pt plus 1fill [\the\scratchskip] % new value
+% \scratchskip = 10pt plus 1fi l l [\the\scratchskip] % also works
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-normalization.tex b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-normalization.tex
index 36d4390aaff..64ceaa353c0 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-normalization.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-normalization.tex
@@ -62,26 +62,49 @@ The decision making is influenced by quite some factors, like:
\stopitem
\stopitemize
-In traditional \TEX\ it doesn't really matter how the resulting boxes look like,
-as long as the following steps can handle them, and those steps don't look into
-those boxes. In fact, unless you unpack a box, only the backend deals with the
-content. But in \LUATEX\ we have callbacks that hook into several stages and {\em
-can} look into the constructed boxes. In \LUATEX\ these boxes also have embedded
-directional information (needed by the backend) and (although that is seldom
-used) left or right boxed material, a features inherited from \ALEPH|/|\OMEGA.
-And when messing around with the content of boxes one has to know what can be
-seen there. In principle the code can be reorganized a it but adding additional
-functionality is not that trivial because we want to stay close to the original
-implementation, even if it has been messed up a bit by successive additions.
-Eventually I might give it a try to integrate all these features a bit better,
-but on the other hand: it works.
+% In traditional \TEX\ it doesn't really matter how the resulting boxes look like,
+% as long as the following steps can handle them, and those steps don't look into
+% those boxes. In fact, unless you unpack a box, only the backend deals with the
+% content. But in \LUATEX\ we have callbacks that hook into several stages and {\em
+% can} look into the constructed boxes. In \LUATEX\ these boxes also have embedded
+% directional information (needed by the backend) and (although that is seldom
+% used) left or right boxed material, a features inherited from \ALEPH|/|\OMEGA.
+% And when messing around with the content of boxes one has to know what can be
+% seen there. In principle the code can be reorganized a it but adding additional
+% functionality is not that trivial because we want to stay close to the original
+% implementation, even if it has been messed up a bit by successive additions.
+% Eventually I might give it a try to integrate all these features a bit better,
+% but on the other hand: it works.
+%
+% \starttexdefinition Sample #1#2
+% \startluacode
+% document.normalizestate = nodes.getnormalizeline()
+% nodes.setnormalizeline(#1)
+% \stopluacode
+% \startsubsubject[title={normalization #1, #2}]
+% \typebuffer[#2]
+% \startlinecorrection
+% \forgetall
+% \start
+% \setupalign[verytolerant,stretch]
+% \showmakeup[line,hbox,vbox,glue]
+% \vbox{\getbuffer[#2]\samplefile{sapolsky}}
+% \stop
+% \par
+% \stoplinecorrection
+% \stopsubject
+% \startluacode
+% nodes.setnormalizeline(document.normalizestate)
+% \stopluacode
+% \stoptexdefinition
+
+\newcount\OldNormalizeLineMode
\starttexdefinition Sample #1#2
- \startluacode
- document.normalizestate = nodes.getnormalizeline()
- nodes.setnormalizeline(#1)
- \stopluacode
- \startsubsubject[title={normalization #1, #2}]
+ \OldNormalizeLineMode\normalizelinemode
+ \bitwiseflip \normalizelinemode \normalizelinemodecode
+ \bitwiseflip \normalizelinemode \indentskipmodecode
+ \startsubsubject[title={#1}]
\typebuffer[#2]
\startlinecorrection
\forgetall
@@ -93,9 +116,7 @@ but on the other hand: it works.
\par
\stoplinecorrection
\stopsubject
- \startluacode
- nodes.setnormalizeline(document.normalizestate)
- \stopluacode
+ \normalizelinemode\OldNormalizeLineMode
\stoptexdefinition
\startbuffer[sample-1]
@@ -130,108 +151,113 @@ but on the other hand: it works.
\hangafter = 3
\stopbuffer
-In the next examples we show how the result of typesetting a paragraph looks
-like. We use the Sapolsky quote from the distribution. The cyan glue nodes are
-the left and right skip nodes, and the gray one at the end of the last line
-represents the parfill skip. The magenta ones at the edge are baseline skips. An
-indentation is shown in gray too. As experiment we have four normalization levels
-but in the end only the highest level makes sense, simply because normalization
-makes no sense unless one consistently normalizes all. We just keep the
-granularity because it makes it possible to explain what gets done.
-
-\texdefinition{Sample}{0}{sample-1}
-\texdefinition{Sample}{0}{sample-2}
-\texdefinition{Sample}{0}{sample-3}
-\texdefinition{Sample}{0}{sample-4}
-
-You might have noticed that the right skip is always there but the left skip is
-absent when it is zero. As said, as long as the result is okay, it does not
-really matter. But \unknown\ in \LUATEX\ (and therefore \CONTEXT) it can have
-consequences because there we can kick in a callback that does something with
-lines. Such a callback often has to deal with these specific glues and them being
-optional makes for more testing. The more predictable the order is, the better.
-Although we can easily normalize lines (in a callback) to always have a left skip
-too it is also an option in the engine.
-
-\texdefinition{Sample}{1}{sample-1}
-\texdefinition{Sample}{1}{sample-2}
-\texdefinition{Sample}{1}{sample-3}
-\texdefinition{Sample}{1}{sample-4}
-
-In the previous examples there are always left skips as well as right skips. It
-makes no sense to have an option to omit both zero left and right skips, because
-that again is unpredictable. But we can go further.
-
-\texdefinition{Sample}{2}{sample-1}
-\texdefinition{Sample}{2}{sample-2}
-\texdefinition{Sample}{2}{sample-3}
-\texdefinition{Sample}{2}{sample-4}
-
-In these examples the indentation has been turned into a glue as well (actually
-it is more a kern but using a glue makes more sense). The hanging indentation
-however is not seen here: it is not represented by glue but instead sort of
-hidden in the width of the box and a shift of its content.
-
-\texdefinition{Sample}{3}{sample-1}
-\texdefinition{Sample}{3}{sample-2}
-\texdefinition{Sample}{3}{sample-3}
-\texdefinition{Sample}{3}{sample-4}
-
-In the previous examples the hanging indentation is turned into left and right
-hang skips. These cannot be set at the \TEX\ end, but are injected when we
-instruct the normalizer to do so.
-
-\texdefinition{Sample}{4}{sample-1}
-\texdefinition{Sample}{4}{sample-2}
-\texdefinition{Sample}{4}{sample-3}
-\texdefinition{Sample}{4}{sample-4}
-
-The previous examples differ from the previous set in that they push these hang
-related glue nodes before the left and after the right skip. As I couldn't make
-up my mind yet, I let \LUAMETATEX\ just provide both variants.
-
-The option to keep hang related information explicitly in the line has some
-consequences. First of all, we now have glue and not some shift|/|width
-combination. Second, we have introduced an incompatibility: the lines now always
-have the proper width. You might have noticed that but we can show it more
-explicitly. We use two parameter sets
-
-\startbuffer[sample-5]
- \hangindent = 20pt
- \hangafter = 0
-\stopbuffer
-
-\startbuffer[sample-6]
- \hangindent =-20pt
- \hangafter = 0
-\stopbuffer
-
-\Sample{0}{sample-5}
-\Sample{4}{sample-5}
-
-\Sample{0}{sample-6}
-\Sample{4}{sample-6}
-
-A not yet mention part of the normalization is that, because they are no longer
-of relevance, the special local par nodes have been removed. The one that starts
-a paragraph is turned into a normal directional node if needed, so that we get
-properly balanced pairs of directional nodes. It must been said that the code
-that does all this is a bit of a mess. We want to stay close to the original
-code, but we also need to deal with all these extensions, like directions,
-protrusion, extra boxes, etc.
-
-Not shown here is that there is a fifth mode of operation. When we enable that
-level an overfull box will get a correction skip so that the right skip etc are
-properly aligned. How useful this is: we'll see.
-
-Now, when I decide to keep this feature, which can be set at the \LUA\ end to do
-the previously mentioned tasks, depending on a feature level ranging from zero to
-four, I also need to check the impact on existing \CONTEXT\ code, which
-(currently) is complicated by the fact that most is shared between \MKIV\ and
-\LMTX, and only \LUAMETATEX\ has this normalization feature. I will probably
-enable it for a while locally in order to see if there are side effects. Then,
-when the code base gets adapted, we have to assume that normalization happens, so
-there is no way back.
+% In the next examples we show how the result of typesetting a paragraph looks
+% like. We use the Sapolsky quote from the distribution. The cyan glue nodes are
+% the left and right skip nodes, and the gray one at the end of the last line
+% represents the parfill skip. The magenta ones at the edge are baseline skips. An
+% indentation is shown in gray too. As experiment we have four normalization levels
+% but in the end only the highest level makes sense, simply because normalization
+% makes no sense unless one consistently normalizes all. We just keep the
+% granularity because it makes it possible to explain what gets done.
+%
+% \texdefinition{Sample}{0}{sample-1}
+% \texdefinition{Sample}{0}{sample-2}
+% \texdefinition{Sample}{0}{sample-3}
+% \texdefinition{Sample}{0}{sample-4}
+%
+% You might have noticed that the right skip is always there but the left skip is
+% absent when it is zero. As said, as long as the result is okay, it does not
+% really matter. But \unknown\ in \LUATEX\ (and therefore \CONTEXT) it can have
+% consequences because there we can kick in a callback that does something with
+% lines. Such a callback often has to deal with these specific glues and them being
+% optional makes for more testing. The more predictable the order is, the better.
+% Although we can easily normalize lines (in a callback) to always have a left skip
+% too it is also an option in the engine.
+%
+% \texdefinition{Sample}{1}{sample-1}
+% \texdefinition{Sample}{1}{sample-2}
+% \texdefinition{Sample}{1}{sample-3}
+% \texdefinition{Sample}{1}{sample-4}
+%
+% In the previous examples there are always left skips as well as right skips. It
+% makes no sense to have an option to omit both zero left and right skips, because
+% that again is unpredictable. But we can go further.
+%
+% \texdefinition{Sample}{2}{sample-1}
+% \texdefinition{Sample}{2}{sample-2}
+% \texdefinition{Sample}{2}{sample-3}
+% \texdefinition{Sample}{2}{sample-4}
+%
+% In these examples the indentation has been turned into a glue as well (actually
+% it is more a kern but using a glue makes more sense). The hanging indentation
+% however is not seen here: it is not represented by glue but instead sort of
+% hidden in the width of the box and a shift of its content.
+%
+% \texdefinition{Sample}{3}{sample-1}
+% \texdefinition{Sample}{3}{sample-2}
+% \texdefinition{Sample}{3}{sample-3}
+% \texdefinition{Sample}{3}{sample-4}
+%
+% In the previous examples the hanging indentation is turned into left and right
+% hang skips. These cannot be set at the \TEX\ end, but are injected when we
+% instruct the normalizer to do so.
+%
+% \texdefinition{Sample}{4}{sample-1}
+% \texdefinition{Sample}{4}{sample-2}
+% \texdefinition{Sample}{4}{sample-3}
+% \texdefinition{Sample}{4}{sample-4}
+%
+% The previous examples differ from the previous set in that they push these hang
+% related glue nodes before the left and after the right skip. As I couldn't make
+% up my mind yet, I let \LUAMETATEX\ just provide both variants.
+%
+% The option to keep hang related information explicitly in the line has some
+% consequences. First of all, we now have glue and not some shift|/|width
+% combination. Second, we have introduced an incompatibility: the lines now always
+% have the proper width. You might have noticed that but we can show it more
+% explicitly. We use two parameter sets
+%
+% \startbuffer[sample-5]
+% \hangindent = 20pt
+% \hangafter = 0
+% \stopbuffer
+%
+% \startbuffer[sample-6]
+% \hangindent =-20pt
+% \hangafter = 0
+% \stopbuffer
+%
+% \Sample{0}{sample-5}
+% \Sample{4}{sample-5}
+%
+% \Sample{0}{sample-6}
+% \Sample{4}{sample-6}
+
+\texdefinition{Sample}{Sample 1}{sample-1}
+\texdefinition{Sample}{Sample 2}{sample-2}
+\texdefinition{Sample}{Sample 3}{sample-3}
+\texdefinition{Sample}{Sample 4}{sample-4}
+
+% A not yet mention part of the normalization is that, because they are no longer
+% of relevance, the special local par nodes have been removed. The one that starts
+% a paragraph is turned into a normal directional node if needed, so that we get
+% properly balanced pairs of directional nodes. It must been said that the code
+% that does all this is a bit of a mess. We want to stay close to the original
+% code, but we also need to deal with all these extensions, like directions,
+% protrusion, extra boxes, etc.
+%
+% Not shown here is that there is a fifth mode of operation. When we enable that
+% level an overfull box will get a correction skip so that the right skip etc are
+% properly aligned. How useful this is: we'll see.
+%
+% Now, when I decide to keep this feature, which can be set at the \LUA\ end to do
+% the previously mentioned tasks, depending on a feature level ranging from zero to
+% four, I also need to check the impact on existing \CONTEXT\ code, which
+% (currently) is complicated by the fact that most is shared between \MKIV\ and
+% \LMTX, and only \LUAMETATEX\ has this normalization feature. I will probably
+% enable it for a while locally in order to see if there are side effects. Then,
+% when the code base gets adapted, we have to assume that normalization happens, so
+% there is no way back.
\stopchapter
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-numbers.tex b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-numbers.tex
new file mode 100644
index 00000000000..9b8e10a5601
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-numbers.tex
@@ -0,0 +1,365 @@
+% language=us
+
+\startcomponent evenmore-numbers
+
+\environment evenmore-style
+
+\startchapter[title={Numbers}]
+
+% \startsection[title={Introduction}]
+
+A few decades of programming in the \TEX\ language can make one wish for certain
+features. It will therefore be no surprise that in \LUATEX\ (and even more in
+\LUAMETATEX) we have some additional functionality. However, I have to admit that
+some of these are not used that much in \CONTEXT\ \MKIV\ and \LMTX. The reason is
+that some wishes date from \MKII\ times and because we now have \LUA\ we actually
+don't need that many new fancy features. Also, it makes no sense to rewrite
+mechanisms that are already working well. However, in order to fully exploit the
+possibilities that \LUA\ gives, there are some additions that relate to the way
+this language can communicate with \TEX. Of course there's also the issue of a
+potentially enhanced performance, but there is not much to gain in that
+department.
+
+A side effect of adding features, of which some are just there to complete the
+picture, or, as mentioned, because they were supposed to make sense, is that I
+make examples. Here I show the result of one of these experiments. I have no clue
+how useful this is, but I've learned not to underestimate users in their demands
+and creativity.
+
+Internally, \TEX\ does all in 32 bit integers. When you say:
+
+\starttyping
+\scratchcounter 123
+\scratchdimen 123pt
+\stoptyping
+
+the \type {123} gets assigned to a count register and the \type {123pt} is
+assigned to a dimen register but actually that is then also an integer: the
+internal unit of a dimen is a scaled point (sp) and only when its value is shown
+to the user, a real number can show up, followed by the \type {pt} unit. The
+precision is limited, so you can expect about four decimal positions precision
+here. There is no concept of a floating point number in \TEX, and the only case
+where a float gets used is in the final calculations of glue and even that only
+comes into play in the backend.
+
+So, although I don't really have an application for it in \CONTEXT\ (otherwise
+I'd already added a float data type to the engine), it sounded like a good idea
+to see if we could emulate float support. In the following examples the numbers
+are managed in \LUA\ and therefore they are global. I could make a local variant
+but why complicate matters. These macros start with \type {\lua} to make clear
+that they are not managed by \TEX.
+
+\startbuffer
+\luacardinal bar 123
+\luainteger bar -456
+\luafloat bar 123.456E-3
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We define \type {bar} three times. Each type gets its own hash, so from the
+perspective of \LUA\ its nature is kept: integer or double.
+
+\startbuffer
+\the\luacardinal bar \quad
+\the\luainteger bar \quad
+\the\luafloat bar
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Instead of decimal values, you can also use hexadecimal values (watch the \type
+{p} for exponents):
+
+\startbuffer
+\luacardinal bar 0x123
+\luainteger bar -0x456
+\luafloat bar 0x123.456p-3
+\stopbuffer
+
+\typebuffer \getbuffer
+
+So, now we get:
+
+\startbuffer
+\the\luacardinal bar \quad
+\the\luainteger bar \quad
+\the\luafloat bar
+\stopbuffer
+
+\getbuffer
+
+From these examples you see two kind of usage: setting a value, and using it. It
+is that property that makes them special. Because the macros are implemented
+using \LUA\ calls it means that at the \LUA\ end we know what usage is expected.
+And it is that dualistic property that I wanted to explore but that in the end
+only makes sense it a very few cases, but sometimes those few are important. We
+could of course two macros, a setter and a getter, but using one kind of its in.
+
+The setters accept an optional equal sign, as in:
+
+\startbuffer
+\luainteger gnu= 123456 \luafloat gnu= 123.456e12
+\luainteger gnu = 123456 \luafloat gnu = 123.456e12
+\luainteger gnu =123456 \luafloat gnu =123.456e12
+\stopbuffer
+
+\typebuffer
+
+Although \LUA\ is involved in picking up the value, storing it someplace, and
+retrieving it on demand, performance is pretty good. You probably won't notice
+the overhead anyway.
+
+The values that \type{\the} returns are serialized numbers. However, sometimes
+you want what \TEX\ sees as a numeric token, For that we have these variants
+
+\startbuffer
+\luadimen test 100pt
+\scratchdimen = .25 \luadimen test
+\the\scratchdimen
+\stopbuffer
+
+\typebuffer
+
+Which produces the expected value: {\tttf \inlinebuffer}, something that depends
+on the fact that the dimension is not a serialized. Talking of serialization,
+there are several ways that \LUA\ can do that so let's give some examples. We
+start with some definitions. Beware, floats and cardinals are stored
+independently!
+
+\startbuffer
+\luacardinal x = -123
+\luacardinal y = 456
+
+\luafloat x = 123.123
+\luafloat y = -456.456
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We have a macro \type {\luaexpression} (not to be confused with \type {\luaexpr}) that
+takes an optional keyword:
+
+\startbuffer
+- : \luaexpression {n.x + 2*n.y}
+f : \luaexpression float {n.x + 2*n.y}
+i : \luaexpression integer {n.x + 2*n.y}
+c : \luaexpression cardinal {n.x + 2*n.y}
+b : \luaexpression boolean {n.x + 2*n.y}
+l : \luaexpression lua {n.x + 2*n.y}
+\stopbuffer
+
+\typebuffer
+
+The serialization can be different for these cases:
+
+\startlines
+\tt \getbuffer
+\stoplines
+
+The \type {numbers} namespace resolves to a float, integer or cardinal (in that
+order) and calculations take place as in \LUA. If you only use integers then
+normally \LUA\ will also serialize them as such.
+
+Here is another teaser. Say that we set the \type {scratchdimen} register to
+a value:
+
+\startbuffer
+\scratchdimen 123.456pt
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We now introduce the \type {\nodimen} macro, that can be used this way:
+
+\startbuffer
+[\the\scratchdimen] [\the\nodimen\scratchdimen]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+which is not that spectacular. Nor is this:
+
+\startbuffer
+\nodimen\scratchdimen = 654.321pt
+\stopbuffer
+
+\typebuffer \getbuffer
+
+But how about this:
+
+\starttabulate[|T|T|]
+\NC \type {\the\nodimen bp \scratchdimen} \NC \the\nodimen bp \scratchdimen \NC \NR
+\NC \type {\the\nodimen cc \scratchdimen} \NC \the\nodimen cc \scratchdimen \NC \NR
+\NC \type {\the\nodimen cm \scratchdimen} \NC \the\nodimen cm \scratchdimen \NC \NR
+\NC \type {\the\nodimen dd \scratchdimen} \NC \the\nodimen dd \scratchdimen \NC \NR
+\NC \type {\the\nodimen in \scratchdimen} \NC \the\nodimen in \scratchdimen \NC \NR
+\NC \type {\the\nodimen mm \scratchdimen} \NC \the\nodimen mm \scratchdimen \NC \NR
+\NC \type {\the\nodimen nc \scratchdimen} \NC \the\nodimen nc \scratchdimen \NC \NR
+\NC \type {\the\nodimen nd \scratchdimen} \NC \the\nodimen nd \scratchdimen \NC \NR
+\NC \type {\the\nodimen pt \scratchdimen} \NC \the\nodimen pt \scratchdimen \NC \NR
+\NC \type {\the\nodimen sp \scratchdimen} \NC \the\nodimen sp \scratchdimen \NC \NR
+\stoptabulate
+
+So here we have a curious mix of setter and getter. The setting part is not that
+interesting but we just provide it as convenience (and demo). Of course we can
+have 10 specific macros instead. Keep in mind that this is a low level macro, so
+it doesn't use the normal \CONTEXT\ user interface.
+
+A bit more complex are one or two dimensional arrays. Again this is an example
+implementation where users can come up with more ideas.
+
+\startbuffer
+\newarray name integers type integer nx 2 ny 2
+\newarray name booleans type boolean nx 2 ny 2
+\newarray name floats type float nx 2 ny 2
+\newarray name dimensions type dimension nx 4
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here we define three two|-|dimensional assays and one one|-|dimensional
+array. The type determines the initialization as well as the scanner and
+serializer. Values can be set as follows:
+
+\startbuffer
+\arrayvalue integers 1 2 4 \arrayvalue integers 2 1 8
+\arrayvalue booleans 1 2 true \arrayvalue booleans 2 1 true
+\arrayvalue floats 1 2 12.34 \arrayvalue floats 2 1 34.12
+\arrayvalue dimensions 1 12.34pt \arrayvalue dimensions 3 34.12pt
+\stopbuffer
+
+\typebuffer \getbuffer
+
+If you want to check an array on the console, you can say:
+
+\starttyping
+\showarray integers
+\stoptyping
+
+We now access some values. Apart from the float these are (sort of) native data
+types.
+
+\startbuffer
+[\the\arrayvalue integers 1 2]
+[\the\arrayvalue booleans 1 2]
+[\the\arrayvalue floats 1 2]
+[\the\arrayvalue dimensions 1 ]\crlf
+[\the\arrayvalue integers 2 1]
+[\the\arrayvalue booleans 2 1]
+[\the\arrayvalue floats 2 1]
+[\the\arrayvalue dimensions 3]
+\stopbuffer
+
+\typebuffer
+
+This produces:
+
+\getbuffer
+
+You can of course use these values in many ways:
+
+\startbuffer
+\dostepwiserecurse{1}{4}{1}{
+ [\the\arrayvalue dimensions #1 :
+ \luaexpression dimen {math.sind(30) * a.dimensions[#1]}]
+}
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+\getbuffer
+
+In addition to the already seen integer and dimension variables fed back into
+\TEX, we also have booleans. These are just integers with the value zero or one.
+In order to make their use easier there is a new \type {\ifboolean} primitive
+that takes such a bit:
+
+\startbuffer
+slot 1 is \ifboolean\arrayequals dimensions 1 0pt zero \else not zero \fi
+slot 2 is \ifboolean\arrayequals dimensions 2 0pt zero \else not zero \fi
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\startlines
+\getbuffer
+\stoplines
+
+A variant is a comparison macro. Of course we can use the dimen comparison
+conditional instead:
+
+\startbuffer
+slot 1: \ifcase\arraycompare dimensions 1 3pt lt \or eq \else gt \fi zero
+slot 2: \ifcase\arraycompare dimensions 2 3pt lt \or eq \else gt \fi zero
+slot 3: \ifcase\arraycompare dimensions 3 3pt lt \or eq \else gt \fi zero
+slot 4: \ifcase\arraycompare dimensions 4 3pt lt \or eq \else gt \fi zero
+
+slot 1: \ifcmpdim\arrayvalue dimensions 1 3pt lt \or eq \else gt \fi zero
+slot 2: \ifcmpdim\arrayvalue dimensions 2 3pt lt \or eq \else gt \fi zero
+slot 3: \ifcmpdim\arrayvalue dimensions 3 3pt lt \or eq \else gt \fi zero
+slot 4: \ifcmpdim\arrayvalue dimensions 4 3pt lt \or eq \else gt \fi zero
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\startlines
+\getbuffer
+\stoplines
+
+Anyway, the question is: do we need this kind of trickery, and if so, what more
+is needed? But beware: we do have \LUA\ anyway, so there is no need for a complex
+user interface at the \TEX\ end just for the sake of it looking more \TEX. The
+above shows a bit what is possible.
+
+It is too soon to discuss the low level interface because it still evolves. After
+some initial experiments, I decided to follow a slightly different route, and
+often the third implementation starts to look what I like more.
+
+% \newarray name whatever type integer nx 100 ny 100
+%
+% \testfeatureonce{1}{
+% \dorecurse {100} {
+% \dorecurse {100} {
+% \scratchcounter \arrayvalue whatever ##1 ####1 \relax
+% }
+% }
+% } \elapsedtime
+
+% \startluacode
+% local whatever = { foo = true, bar = true }
+%
+% interfaces.implement {
+% name = "MyMatch",
+% public = true,
+% value = true,
+% actions = function(b)
+% -- we gobble spaces
+% return
+% tokens.functionvalues.boolean,
+% whatever[tokens.scanners.word(true)] or false
+% end,
+% }
+% \stopluacode
+%
+% [\ifboolean\MyMatch foo YES\else NOP\fi]
+% [\ifboolean\MyMatch rab YES\else NOP\fi]
+% [\ifboolean\MyMatch bar YES\else NOP\fi]
+% [\ifboolean\MyMatch oof YES\else NOP\fi]
+%
+% \def\Matched#1{\ifboolean\MyMatch #1 }
+%
+% [\ifcondition\Matched{oof}YES\else NOP\fi]
+% [\ifcondition\Matched{foo}YES\else NOP\fi]
+
+% \stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-parameters.tex b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-parameters.tex
new file mode 100644
index 00000000000..b07378fae96
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-parameters.tex
@@ -0,0 +1,449 @@
+% language=us
+
+% This feature was done mid May 2020 with Alien Chatter (I really need to find the
+% original cd's) in the background.
+
+\environment evenmore-style
+
+\startcomponent evenmore-parameters
+
+\startchapter[title=Parameters]
+
+When \TEX\ reads input it either does something directly, like setting a
+register, loading a font, turning a character into a glyph node, packaging a box,
+or it sort of collects tokens and stores them somehow, in a macro (definition),
+in a token register, or someplace temporary to inject them into the input later.
+Here we'll be discussing macros, which have a special token list containing the
+preamble defining the arguments and a body doing the real work. For instance when
+you say:
+
+\starttyping[option=TEX]
+\def\foo#1#2{#1 + #2 + #1 + #2}
+\stoptyping
+
+the macro \type {\foo} is stored in such a way that it knows how to pick up the
+two arguments and when expanding the body, it will inject the collected arguments
+each time a reference like \type {#1} or \type {#2} is seen. In fact, quite
+often, \TEX\ pushes a list of tokens (like an argument) in the input stream and
+then detours in taking tokens from that list. Because \TEX\ does all its memory
+management itself the price of all that copying is not that high, although during
+a long and more complex run the individual tokens that make the forward linked
+list of tokens get scattered in token memory and memory access is still the
+bottleneck in processing.
+
+A somewhat simplified view of how a macro like this gets stored is the following:
+
+\starttyping
+hash entry "foo" with property "macro call" =>
+
+ match (# property stored)
+ match (# property stored)
+ end of match
+
+ match reference 1
+ other character +
+ match reference 2
+ other character +
+ match reference 1
+ other character +
+ match reference 2
+\stoptyping
+
+When a macro gets expanded, the scanner first collects all the passed arguments
+and then pushes those (in this case two) token lists on the parameter stack. Keep
+in mind that due to nesting many kinds of stacks play a role. When the body gets
+expanded and a reference is seen, the argument that it refers to gets injected
+into the input, so imagine that we have this definition:
+
+\starttyping[option=TEX]
+\foo#1#2{\ifdim\dimen0=0pt #1\else #2\fi}
+\stoptyping
+
+and we say:
+
+\starttyping[option=TEX]
+\foo{yes}{no}
+\stoptyping
+
+then it's as if we had typed:
+
+\starttyping[option=TEX]
+\ifdim\dimen0=0pt yes\else no\fi
+\stoptyping
+
+So, you'd better not have something in the arguments that messes up the condition
+parser! From the perspective of an expansion machine it all makes sense. But it
+also means that when arguments are not used, they still get parsed and stored.
+Imagine using this one:
+
+\starttyping[option=TEX]
+\def\foo#1{\iffalse#1\oof#1\oof#1\oof#1\oof#1\fi}
+\stoptyping
+
+When \TEX\ sees that the condition is false it will enter a fast scanning mode
+where it only looks at condition related tokens, so even if \type {\oof} is not
+defined this will work ok:
+
+\starttyping[option=TEX]
+\foo{!}
+\stoptyping
+
+But when we say this:
+
+\starttyping[option=TEX]
+\foo{\else}
+\stoptyping
+
+It will bark! This is because each \type {#1} reference will be resolved, so we
+effectively have
+
+\starttyping[option=TEX]
+\def\foo#1{\iffalse\else\oof\else\oof\else\oof\else\oof\else\fi}
+\stoptyping
+
+which is not good. On the other hand, since expansion takes place in quick
+parsing mode, this will work:
+
+\starttyping[option=TEX]
+\def\oof{\else}
+\foo\oof
+\stoptyping
+
+which actually is:
+
+\starttyping[option=TEX]
+\def\foo#1{\iffalse\oof\oof\oof\oof\oof\oof\oof\oof\oof\fi}
+\stoptyping
+
+So, a reference to an argument effectively is just a replacement. As long as you
+keep that in mind, and realize that while \TEX\ is skipping \quote {if} branches
+nothing gets expanded, you're okay.
+
+Most users will associate the \type {#} character with macro arguments or
+preambles in low level alignments, but since most macro packages provide a higher
+level set of table macros the latter is less well known. But, as often with
+characters in \TEX, you can do magic things:
+
+\starttyping[option=TEX]
+\catcode`?=\catcode`#
+
+\def\foo #1#2?3{?1?2?3} \meaning\foo\space=>\foo{1}{2}{3}\par
+\def\foo ?1#2?3{?1?2?3} \meaning\foo\space=>\foo{1}{2}{3}\par
+\def\foo ?1?2#3{?1?2?3} \meaning\foo\space=>\foo{1}{2}{3}\par
+\stoptyping
+
+Here the question mark also indicates a macro argument. However, when expanded
+we see this as result:
+
+\starttyping
+macro:#1#2?3->?1?2?3 =>123
+macro:?1#2?3->?1?2?3 =>123
+macro:?1?2#3->#1#2#3 =>123
+\stoptyping
+
+The last used argument signal character (officially called a match character,
+here we have two that fit that category, \type {#} and \type {?}) is used in the
+serialization! Now, there is an interesting aspect here. When \TEX\ stores the
+preamble, as in our first example:
+
+\starttyping
+ match (# property stored)
+ match (# property stored)
+ end of match
+\stoptyping
+
+the property is stored, so in the later example we get:
+
+\starttyping
+ match (# property stored)
+ match (# property stored)
+ match (? property stored)
+ end of match
+\stoptyping
+
+But in the macro body the number is stored instead, because we need it as
+reference to the parameter, so when that bit gets serialized \TEX\ (or more
+accurately: \LUATEX, which is what we're using here) doesn't know what specific
+signal was used. When the preamble is serialized it does keep track of the last
+so|-|called match character. This is why we see this inconsistency in rendering.
+
+A simple solution would be to store the used signal for the match argument, which
+probably only takes a few lines of extra code (using a nine integer array instead
+of a single integer), and use that instead. I'm willing to see that as a bug in
+\LUATEX\ but when I ran into it I was playing with something else: adding the
+ability to prevent storing unused arguments. But the resulting confusion can make
+one wonder why we do not always serialize the match character as \type {#}.
+
+It was then that I noticed that the preamble stored the match tokens and not the
+number and that \TEX\ in fact assumes that no mixture is used. And, after
+prototyping that in itself trivial change I decided that in order to properly
+serialize this new feature it also made sense to always serialize the match token
+as \type {#}. I simply prefer consistency over confusion and so I caught two
+flies in one stroke. The new feature is indicated with a \type {#0} parameter:
+
+\startbuffer
+
+\bgroup
+\catcode`?=\catcode`#
+
+\def\foo ?1?0?3{?1?2?3} \meaning\foo\space=>\foo{1}{2}{3}\crlf
+\def\foo ?1#0?3{?1?2?3} \meaning\foo\space=>\foo{1}{2}{3}\crlf
+\def\foo #1#2?3{?1?2?3} \meaning\foo\space=>\foo{1}{2}{3}\crlf
+\def\foo ?1#2?3{?1?2?3} \meaning\foo\space=>\foo{1}{2}{3}\crlf
+\def\foo ?1?2#3{?1?2?3} \meaning\foo\space=>\foo{1}{2}{3}\crlf
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\start
+\getbuffer
+\stop
+
+So, what is the rationale behind this new \type{#0} variant? Quite often you
+don't want to do something with an argument at all. This happens when a macro
+acts upon for instance a first argument and then expands another macro that
+follows up but only deals with one of many arguments and discards the rest. Then
+it makes no sense to store unused arguments. Keep in mind that in order to use it
+more than once an argument does need to be stored, because the parser only looks
+forward. In principle there could be some optimization in case the tokens come
+from macros but we leave that for now. So, when we don't need an argument, we can
+avoid storing it and just skip over it. Consider the following:
+
+\startbuffer
+\def\foo #1{\ifnum#1=1 \expandafter\fooone\else\expandafter\footwo\fi}
+\def\fooone#1#0{#1}
+\def\footwo#0#2{#2}
+\foo{1}{yes}{no}
+\foo{0}{yes}{no}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get:
+
+\getbuffer
+
+Just for the record, tracing of a macro shows that indeed there is no argument
+stored:
+
+\starttyping[option=TEX]
+\def\foo#1#0#3{....}
+\foo{11}{22}{33}
+\foo #1#0#3->....
+#1<-11
+#2<-
+#3<-33
+\stoptyping
+
+Now, you can argue, what is the benefit of not storing tokens? As mentioned
+above, the \TEX\ engines do their own memory management. \footnote {An added
+benefit is that dumping and undumping is relatively efficient too.} This has
+large benefits in performance especially when one keeps in mind that tokens get
+allocated and are recycled constantly (take only lookahead and push back).
+
+However, even if this means that storing a couple of unused arguments doesn't put
+much of a dent in performance, it does mean that a token sits somewhere in memory
+and that this bit of memory needs to get accessed. Again, this is no big deal on
+a computer where a \TEX\ job can take one core and basically is the only process
+fighting for \CPU\ cache usage. But less memory access might be more relevant in
+a scenario of multiple virtual machines running on the same hardware or multiple
+\TEX\ processes on one machine. I didn't carefully measure that so I might be
+wrong here. Anyway, it's always good to avoid moving around data when there is no
+need for it.
+
+Just to temper expectations with respect to performance, here are some examples:
+
+\starttyping[option=TEX]
+\catcode`!=9 % ignore this character
+\firstoftwoarguments
+ {!!!!!!!!!!!!!!!!!!!}{!!!!!!!!!!!!!!!!!!!}
+\secondoftwoarguments
+ {!!!!!!!!!!!!!!!!!!!}{!!!!!!!!!!!!!!!!!!!}
+\secondoffourarguments
+ {!!!!!!!!!!!!!!!!!!!}{!!!!!!!!!!!!!!!!!!!}
+ {!!!!!!!!!!!!!!!!!!!}{!!!!!!!!!!!!!!!!!!!}
+\stoptyping
+
+In \CONTEXT\ we define these macros as follows:
+
+\starttyping[option=TEX]
+\def\firstoftwoarguments #1#2{#1}
+\def\secondoftwoarguments #1#2{#2}
+\def\secondoffourarguments#1#2#3#4{#2}
+\stoptyping
+
+The performance of 2 million expansions is the following (probably half or less
+on a more modern machine):
+
+\starttabulate[||||]
+\BC macro \BC total \BC step \NC \NR
+\NC \type {\firstoftwoarguments} \NC 0.245 \NC 0.000000123 \NC \NR
+\NC \type {\secondoftwoarguments} \NC 0.251 \NC 0.000000126 \NC \NR
+\NC \type {\secondoffourarguments} \NC 0.390 \NC 0.000000195 \NC \NR
+\stoptabulate
+
+But we could use this instead:
+
+\starttyping[option=TEX]
+\def\firstoftwoarguments #1#0{#1}
+\def\secondoftwoarguments #0#2{#2}
+\def\secondoffourarguments#0#2#0#0{#2}
+\stoptyping
+
+which gives:
+
+\starttabulate[||||]
+\BC macro \BC total \BC step \NC \NR
+\NC \type {\firstoftwoarguments} \NC 0.229 \NC 0.000000115 \NC \NR
+\NC \type {\secondoftwoarguments} \NC 0.236 \NC 0.000000118 \NC \NR
+\NC \type {\secondoffourarguments} \NC 0.323 \NC 0.000000162 \NC \NR
+\stoptabulate
+
+So, no impressive differences, especially when one considers that when that many
+expansions happen in a run, getting the document itself rendered plus expanding
+real arguments (not something defined to be ignored) will take way more time
+compared to this. I always test an extension like this on the test suite
+\footnote {Currently some 1600 files that take 24 minutes plus or minus 30
+seconds to process on a high end 2013 laptop. The 260 page manual with lots of
+tables, verbatim and \METAPOST\ images takes around 11 seconds. A few
+milliseconds more or less don't really show here. I only time these runs because
+I want to make sure that there are no dramatic consequences.} as well as the
+\LUAMETATEX\ manual (which takes about 11 seconds) and although one can notice a
+little gain, it makes more sense not to play music on the same machine as we run
+the \TEX\ job, if gaining milliseconds is that important. But, as said, it's more
+about unnecessary memory access than about \CPU\ cycles.
+
+This extension is downward compatible and its overhead can be neglected. Okay,
+the serialization now always uses \type {#} but it was inconsistent before, so
+I'm willing to sacrifice that (and I'm pretty sure no \CONTEXT\ user cares or
+will even notice). Also, it's only in \LUAMETATEX\ (for now) so that other macro
+packages don't suffer from this patch. The few cases where \CONTEXT\ can benefit
+from it are easy to isolate for \MKIV\ and \LMTX\ so we can support \LUATEX\ and
+\LUAMETATEX.
+
+I mentioned \LUATEX\ and how it serializes, but for the record, let's see how
+\PDFTEX, which is very close to original \TEX\ in terms of source code, does it.
+If we have this input:
+
+\starttyping[option=TEX]
+\catcode`D=\catcode`#
+\catcode`O=\catcode`#
+\catcode`N=\catcode`#
+\catcode`-=\catcode`#
+\catcode`K=\catcode`#
+\catcode`N=\catcode`#
+\catcode`U=\catcode`#
+\catcode`T=\catcode`#
+\catcode`H=\catcode`#
+
+\def\dek D1O2N3-4K5N6U7T8H9{#1#2#3 #4#6#7#8#9}
+
+{\meaning\dek \tracingall \dek don{}knuth}
+\stoptyping
+
+The meaning gets typeset as:
+
+\starttyping
+macro:D1O2N3-4K5N6U7T8H9->H1H2H3 H4H6H7H8H9don nuth
+\stoptyping
+
+while the tracing reports:
+
+\starttyping
+\dek D1O2N3-4K5N6U7T8H9->H1H2H3 H5H6H7H8H9
+D1<-d
+O2<-o
+N3<-n
+-4<-
+K5<-k
+N6<-n
+U7<-u
+T8<-t
+H9<-h
+\stoptyping
+
+The reason for the difference, as mentioned, is that the tracing uses the
+template and therefore uses the stored match token, while the meaning uses the
+reference match tokens that carry the number and at that time has no access to
+the original match token. Keeping track of that for the sake of tracing would not
+make sense anyway. So, traditional \TEX, which is what \PDFTEX\ is very close to,
+uses the last used match token, the \type {H}. Maybe this example can convince
+you that dropping that bit of log related compatibility is not that much of a
+problem. I just tell myself that I turned an unwanted side effect into a new
+feature.
+
+\subject{A few side notes}
+
+The fact that characters can be given a special meaning is one of the charming
+properties of \TEX. Take these two cases:
+
+\starttyping[option=TEX]
+\bgroup\catcode`\&=5 &\egroup
+\bgroup\catcode`\!=5 !\egroup
+\stoptyping
+
+In both lines there is now an alignment character used outside an alignment. And,
+in both cases the error message is similar:
+
+\starttyping
+! Misplaced alignment tab character &
+! Misplaced alignment tab character !
+\stoptyping
+
+So, indeed the right character is shown in the message. But, as soon as you ask
+for help, there is a difference: in the first case the help is specific for a tab
+character, but in the second case a more generic explanation is given. Just try
+it.
+
+The reason is an explicit check for the ampersand being used as tab character.
+Such is the charm of \TEX. I'll probably opt for a trivial change to be
+consistent here, although in \CONTEXT\ the ampersand is just an ampersand so no
+user will notice.
+
+There are a few more places where, although in principle any character can serve
+any purpose, there are hard coded assumptions, like \type {$} being used for
+math, so a missing dollar is reported, even if math started with another
+character being used to enter math mode. This makes sense because there is no
+urgent need to keep track of what specific character was used for entering math
+mode. An even stronger argument could be that \TEX ies expect dollars to be used
+for that purpose. Of course this works fine:
+
+\starttyping[option=TEX]
+\catcode`€=\catcode`$
+€ \sqrt{x^3} €
+\stoptyping
+
+But when we forget an \type {€} we get messages like:
+
+\starttyping
+! Missing $ inserted
+\stoptyping
+
+or more generic:
+
+\starttyping
+! Extra }, or forgotten $
+\stoptyping
+
+which is definitely a confirmation of \quotation {America first}. Of course we
+can compromise in display math because this is quite okay:
+
+\starttyping[option=TEX]
+\catcode`€=\catcode`$
+$€ \sqrt{x^3} €$
+\stoptyping
+
+unless of course we forget the last dollar in which case we are told that
+
+\starttyping
+! Display math should end with $$
+\stoptyping
+
+so no matter what, the dollar wins. Given how ugly the Euro sign looks I can live
+with this, although I always wonder what character would have been taken if \TEX\
+was developed in another country.
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-parsing.tex b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-parsing.tex
new file mode 100644
index 00000000000..d0cc29db11f
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-parsing.tex
@@ -0,0 +1,425 @@
+% language=us
+
+\environment evenmore-style
+
+\startcomponent evenmore-parsing
+
+\startchapter[title=Parsing]
+
+The macro mechanism is \TEX\ is quite powerful and once you understand the
+concept of mixing parameters and delimiters you can do a lot with it. I assume
+that you know what we're talking about, otherwise quit reading. When grabbing
+arguments, there are a few catches.
+
+\startitemize
+\startitem
+ When they are used, delimiters are mandate: \TEX\ will go on reading an
+ argument till the (current) delimiter condition is met. This means that when
+ you forget one you end up with way more in the argument than expected or even
+ run out of input.
+\stopitem
+\startitem
+ Because specified arguments and delimiters are mandate, when you want to
+ parse input, you often need multi|-|step macros that first pick up the to be
+ parsed input, and then piecewise fetch snippets. Bogus delimiters have to be
+ appended to the original in order to catch a run away argument and checking
+ has to be done to get rid of them when all is ok.
+\stopitem
+\stopitemize
+
+The first item can be illustrated as follows:
+
+\starttyping[option=TEX]
+\def\foo[#1]{...}
+\stoptyping
+
+When \type {\foo} gets expanded \TEX\ first looks for a \type{[} and then starts
+collecting tokens for parameter \type {#1}. It stops doing that when aa \type {]}
+is seen. So,
+
+\starttyping[option=TEX]
+\starttext
+ \foo[whatever
+\stoptext
+\stoptyping
+
+will for sure give an error. When collecting tokens, \TEX\ doesn't expand them so
+the \type {\stoptext} is just turned into a token that gets appended.
+
+The second item is harder to explain (or grasp):
+
+\starttyping[option=TEX]
+\def\foo[#1=#2]{(#1/#2)}
+\stoptyping
+
+Here we expect a key and a value, so these will work:
+
+\starttyping[option=TEX]
+\foo[key=value]
+\foo[key=]
+\stoptyping
+
+while these will fail:
+
+\starttyping[option=TEX]
+\foo[key]
+\foo[]
+\stoptyping
+
+unless we have:
+
+\starttyping[option=TEX]
+\foo[key]=]
+\foo[]=]
+\stoptyping
+
+But, when processing the result, we then need to analyze the found arguments and
+correct for them being wrong. For instance, argument \type {#1} can become \type
+{]} or here \type {key]}. When indeed a valid key|/|value combination is given we
+need to get rid of the two \quote {fixup} tokens \type{=]}. Normally we will have
+multiple key|/|value pairs separated by a comma, and in practice we only need to
+catch the missing equal because we can ignore empty cases. There are plenty of
+examples (rather old old code but also more modern variants) in the \CONTEXT\
+code base.
+
+I will now show some new magic that is available in \LUAMETATEX\ as experimental
+code. It will be tested in \LMTX\ for a while and might evolve in the process.
+
+\startbuffer
+\def\foo#1=#2,{(#1/#2)}
+
+\foo 1=2,\ignorearguments
+\foo 1=2\ignorearguments
+\foo 1\ignorearguments
+\foo \ignorearguments
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Here we pick up a key and value separated by an equal sign. We end the input with
+a special signal command: \type {\ignorearguments}. This tells the parser to quit
+scanning. So, we get this, without any warning with respect to a missing
+delimiter of running away:
+
+\getbuffer
+
+The implementation is actually fairly simple and adds not much overhead.
+Alternatives (and I pondered a few) are just too messy, would remind me too much
+of those awful expression syntaxes, and definitely impact performance of macro
+expansion, therefore: a no|-|go.
+
+Using this new feature, we can implement a key value parser that does a sequence.
+The prototypes used to get here made only use of this one new feature and
+therefore still had to do some testing of the results. But, after looking at the
+code, I decided that a few more helpers could make better looking code. So this
+is what I ended up with:
+
+\startbuffer
+\def\grabparameter#1=#2,%
+ {\ifarguments\or\or
+ % (\whatever/#1/#2)\par%
+ \expandafter\def\csname\namespace#1\endcsname{#2}%
+ \expandafter\grabnextparameter
+ \fi}
+
+\def\grabnextparameter
+ {\expandafterspaces\grabparameter}
+
+\def\grabparameters[#1]#2[#3]%
+ {\def\namespace{#1}%
+ \expandafterspaces\grabparameter#3\ignorearguments\ignorearguments}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Now, this one actually does what the \CONTEXT\ \type {\getparameters} command
+does: setting variables in a namespace. Being a parameter driven macro package
+this kind of macros have been part of \CONTEXT\ since the beginning. There are
+some variants and we also need to deal with the multilingual interface. Actually,
+\MKIV\ (and therefore \LMTX) do things a bit different, but the same principles
+apply.
+
+The \type {\ignorearguments} quits the scanning. Here we need two because we
+actually quit twice. The \type {\expandafterspaces} can be implemented in
+traditional \TEX\ macros but I though it is nice to have it this way; the fact
+that I only now added it has more to do with cosmetics. One could use the already
+somewhat older extension \type {\futureexpandis} (which expands the second or
+third token depending seeing the first, in this variant ignoring spaces) or a
+bunch of good old primitives to do the same. The new conditional \type
+{\ifarguments} can be used to act upon the number of arguments given. It reflects
+the most recently expanded macro. There is also a \type {\lastarguments}
+primitive (that provides the number of arguments.
+
+So, what are the benefits? You might think that it is about performance, but in
+practice there are not that many parameter settings going on. When I process the
+\LUAMETATEX\ manual, only some 5000 times one or more parameters are set. And
+even in a way more complex document that I asked my colleague to run I was a bit
+disappointed that only some 30.000 cases were reported. I know of users who have
+documents with hundreds of thousands of cases, but compared to the rest of
+processing this is not where the performance bottleneck is. \footnote {Think of
+thousands of pages of tables with cell settings applied.} This means that a
+change in implementation like the above is not paying off in significantly better
+runtime: all these low level mechanisms in \CONTEXT\ have been very well
+optimized over the years. And faster machines made old bottlenecks go away
+anyway. Take this use case:
+
+\starttyping[option=TEX]
+\grabparameters
+ [foo]
+ [key0=value0,
+ key1=value1,
+ key2=value2,
+ key3=value3]
+\stoptyping
+
+After this, parameters can be accessed with:
+
+\starttyping[option=TEX]
+\def\getvalue#1#2{\csname#1#2\endcsname}
+\stoptyping
+
+used as:
+
+\starttyping[option=TEX]
+\getvalue{foo}{key2}
+\stoptyping
+
+which takes care of characters normally not permitted in macro names, like the
+digits in this example. Of course some namespace protection can be added, like
+adding a colon between the namespace and the key, but let's take just this one.
+
+Some 10.000 expansions of the grabber take on my machine 0.045 seconds while the
+original \type {\getparameters} takes 0.090 so although for this case we're twice
+as fast, the 0.045 difference will not be noticed on a real run. After all, when
+these parameters are set some action will take place. Also, we don't actually use
+this macro for collecting settings with the \type {\setupsomething} commands, so
+the additional overhead that is involved adds a baseline to performance that can
+turn any gain into noise. But some users might notice some gain. Of course this
+observation might change once we apply this trickery in more places than
+parameter parsing, because I have to admit that there might be other places in
+the support macros where we can benefit: less code, double performance, but these
+are all support macros that made sense in \MKII\ and not that much in \MKIV\ or
+\LMTX\ and are kept just for convenience and backward compatibility. Think of
+some list processing macros. So, as a kind of nostalgic trip I decided to rewrite
+some low level macros anyway, if only to see what is no longer used and|/|or to
+make the code base somewhat (c)leaner.
+
+Elsewhere I introduce the \type {#0} argument indicator. That one will just
+gobbles the argument and does not store a token list on the stack. It saves some
+memory access and token recycling when arguments are not used. Another special
+indicator is \type {#+}. That one will flag an argument to be passed as|-|is. The
+\type {#-} variant will simply discard an argument and move on. The following
+examples demonstrate this:
+
+\startbuffer
+\def\foo [#1]{\detokenize{#1}}
+\def\ofo [#0]{\detokenize{#1}}
+\def\oof [#+]{\detokenize{#1}}
+\def\fof[#1#-#2]{\detokenize{#1#2}}
+\def\fff[#1#0#3]{\detokenize{#1#3}}
+
+\meaning\foo\ : <\foo[{123}]> \crlf
+\meaning\ofo\ : <\ofo[{123}]> \crlf
+\meaning\oof\ : <\oof[{123}]> \crlf
+\meaning\fof\ : <\fof[123]> \crlf
+\meaning\fff\ : <\fof[123]> \crlf
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This gives:
+
+{\tttf \getbuffer}
+
+% \getcommalistsize[a,b,c] \commalistsize\par
+% \getcommalistsize[{a,b,c}] \commalistsize\par
+
+When playing with new features like the one described here, it makes sense to use
+them in existing macros so that they get well tested. Some of the low level
+system files come in different versions: for \MKII, \MKIV\ and \LMTX. The \MKII\
+files often also have the older implementations, so they are also good for
+looking at the history. The \LMTX\ files can be leaner and meaner than the \MKIV\
+files because they use the latest features. \footnote {Some 70 primitives present
+in \LUATEX\ are not in \LUAMETATEX. On the other hand there are also about 70 new
+primitives. Of those gone, most concerned the backend, fonts or no longer
+relevant features from other engines. Of those new, some are really new
+primitives (conditionals, expansion magic), some control previously hardwired
+behaviour, some give access to properties of for instance boxes, and some are
+just variants of existing ones but with options for control.}
+
+When I was rewriting some of these low level \MKIV\ macros using the newer features,
+at some point I wondered why I still had to jump through some hoops. Why not just
+add some more primitives to deal with that? After all, \LUATEX\ and \LUAMETATEX\
+already have more primitives that are helpful in parsing, so a few dozen more lines
+don't hurt. As long as these primitives are generic and not that specific. In this
+particular case we talk about two new conditionals (in addition to the already
+present comparison primitives):
+
+\starttyping[option=TEX]
+\ifhastok <token> {<token list>}
+\ifhastoks {<token list>} {<token list>}
+\ifhasxtoks {<token list>} {<token list>}
+\stoptyping
+
+You can probably guess what they do from their names. The last one is the
+expandable variant of the second one. The first one is the fast one. When playing
+with these I decided to redo the set checker. In \MKII\ that one is done in good
+old \TEX, in \MKIV\ we use \LUA. So, how about going back to \TEX ?
+
+\starttyping[option=TEX]
+\ifhasxtoks {cd} {abcdef}
+\stoptyping
+
+This check is true. But that doesn't work well with a comma separated list, but
+there is a way out:
+
+\starttyping[option=TEX]
+\ifhasxtoks {,cd,} {,ab,cd,ef,}
+\stoptyping
+
+However, when I applied that a user reported that it didn't handle optional
+spaces before commas. So how do we deal with such optional characters tokens?
+
+\startbuffer
+\def\setcontains#1#2{\ifhasxtoks{,#1,}{,#2,}}
+
+\ifcondition\setcontains{cd}{ab,cd,ef}YES \else NO \fi
+\ifcondition\setcontains{cd}{ab, cd, ef}YES \else NO \fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get:
+
+\getbuffer
+
+The \type {\ifcondition} is an old one. When nested in a condition it will be
+seen as an \type {\if...} by the fast skipping scanner, but when expanded it will
+go on and a following macro has to expand to a proper condition. That said, we
+can take care of the optional space by entering some new territory. Look at this:
+
+\startbuffer
+\def\setcontains#1#2{\ifhasxtoks{,\expandtoken 9 "20 #1,}{,#2,}}
+
+\ifcondition\setcontains{cd}{ab,cd,ef}YES \else NO \fi
+\ifcondition\setcontains{cd}{ab, cd, ef}YES \else NO \fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get:
+
+\getbuffer
+
+So how does that work? The \type {\expandtoken} injects a space token with
+catcode~9 which means that it is in the to be ignored category. When a to be
+ignored token is seen, and the to be checked token is a character (letter, other,
+space or ignored) then the character code will be compared. When they match, we
+move on, otherwise we just skip over the ignored token (here the space).
+
+In the \CONTEXT\ code base there are already files that are specific for \MKIV\
+and \LMTX. The most visible difference is that we use the \type {\orelse}
+primitive to construct nicer test trees, and we also use some of the additional
+\type {\future...} and \type {\expandafter...} features. The extensions discussed
+here make for the most recent differences (we're talking end May 2020).
+
+After implementing this trick I decided to look at the macro definition mechanism
+one more time and see if I could also use this there. Before I demonstrate
+another next feature, I will again show the argument extensions, this time with
+a fourth variant:
+
+\startbuffer[definitions]
+\def\TestA#1#2#3{{(#1)(#2)(#3)}}
+\def\TestB#1#0#3{(#1)(#2)(#3)}
+\def\TestC#1#+#3{(#1)(#2)(#3)}
+\def\TestD#1#-#2{(#1)(#2)}
+\stopbuffer
+
+\typebuffer[definitions][option=TEX] \getbuffer[definitions]
+
+The last one specifies a to be thrashed argument: \type {#-}. It goes further
+than the second one (\type {#0}) which still keeps a reference. This is why in
+this last case the third argument gets number \type {2}. The meanings of these
+four are:
+
+\startlines \tttf
+\meaning\TestA
+\meaning\TestB
+\meaning\TestC
+\meaning\TestD
+\stoplines
+
+There are some subtle differences between these variants, as you can see from
+the following examples:
+
+\startbuffer[usage]
+\TestA1{\red 2}3
+\TestB1{\red 2}3
+\TestC1{\red 2}3
+\TestD1{\red 2}3
+\stopbuffer
+
+\typebuffer[usage][option=TEX]
+
+Here you also see the side effect of keeping the braces. The zero argument (\type
+{#0}) is ignored, and the thrashed argument (\type {#-}) can't even be accessed.
+
+\startlines \tttf \getbuffer[usage] \stoplines
+
+In the next example we see two delimiters being used, a comma and a space, but
+they have catcode~9 which flags them as ignored. This is a signal for the parser
+that both the comma and the space can be skipped. The zero arguments are still on
+the parameter stack, but the thrashed ones result in a smaller stack, not that
+the later matters much on today's machines.
+
+\startbuffer
+\normalexpanded {
+ \def\noexpand\foo
+ \expandtoken 9 "2C % comma
+ \expandtoken 9 "20 % space
+ #1=#2]%
+}{(#1)(#2)}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+This means that the next tree expansions won't bark:
+
+\startbuffer
+\foo,key=value]
+\foo, key=value]
+\foo key=value]
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+or expanded:
+
+\startlines \tttf \getbuffer \stoplines
+
+Now, why didn't I add these primitives long ago already? After all, I already
+added dozens of new primitives over the years. To quote Andrew Cuomo, what
+follows now are opinions, not facts.
+
+Decades ago, when \TEX\ showed up, there was no Internet. I remember that I got
+my first copy on floppy disks. Computers were slow and memory was limited. The
+\TEX book was the main resource and writing macros was a kind of art. One could
+not look up solutions, so trial and error was a valid way to go. Figuring out
+what was efficient in terms of memory consumption and runtime was often needed
+too. I remember meetings where one was not taken serious when not talking in the
+right \quote {token}, \quote {node}, \quote {stomach} and \quote {mouth} speak.
+Suggesting extensions could end up in being told that there was no need because
+all could be done in macros or even arguments of the \quotation {who needs that}.
+I must admit that nowadays I wonder to what extend that was related to extensions
+taking away some of the craftmanship and showing off. In a way it is no surprise
+that (even trivial to implement) extensions never surfaced. Of course then the
+question is: will extensions that once were considered not of importance be used
+today? We'll see.
+
+Let's end by saying that, as with other experiments, I might port some of the new
+features in \LUAMETATEX\ to \LUATEX, but only after they have become stable and
+have been tested in \LMTX\ for quite a while.
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-tokens.tex b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-tokens.tex
new file mode 100644
index 00000000000..8c1e3ccb047
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-tokens.tex
@@ -0,0 +1,456 @@
+% language=us
+
+% TODO: copy_node_list : return tail
+% TODO: grabnested
+
+\environment evenmore-style
+
+\startcomponent evenmore-tokens
+
+\startchapter[title=Tokens]
+
+{\em This is mostly a wrapup of some developments, and definitely not a tutorial.}
+
+Talking deep down \TEX\ is talking about tokens and nodes. Roughly spoken, from
+the perspective of the user, tokens are what goes in and stays in (as macro,
+token list of whatever) and nodes is what get produced and eventually results in
+output. A character in the input becomes one token (before expansion) and a
+control sequence like \type {\foo} also is turned into a token. Tokens can be
+linked into lists. This actually means that in the engine we can talk of tokens
+in two ways: the single item with properties that trigger actions, or as compound
+item with that item and a pointer to the next token (called link). In \LUA\ speak
+token memory can be seen as:
+
+\starttyping
+fixmem = {
+ { info, link },
+ { info, link },
+ { info, link },
+ { info, link },
+ ....
+}
+\stoptyping
+
+Both are 32 bit integers. The \type {info} is a combination of a command code (an
+operator) and a so called chr code (operand) and these determine its behaviour.
+For instance the command code can indicate an integer register and the chr code
+then indicates the number of that register. So, like:
+
+\starttyping
+fixmem = {
+ { { cmd, chr}, index_into_fixmem },
+ { { cmd, chr}, index_into_fixmem },
+ { { cmd, chr}, index_into_fixmem },
+ { { cmd, chr}, index_into_fixmem },
+ ....
+}
+\stoptyping
+
+
+In the following line the characters that make three words are tokens (letters),
+so are the space (spacer), the curly braces (begin- and endgroup token) and the
+bold face switch (which becomes one token which resolves to a token list of
+tokens that trigger actions (in this case switching to a bolder font).
+
+\starttyping
+foo {\bf bar} foo
+\stoptyping
+
+When \TEX\ reads a line of input tokens are expanded immediately but a sequence
+can also become part fo a macro body or token list. Here we have $3_{\type{foo}}
++ 1 + 1_{\type+{+} + 1_{\type{\bf}} + 3_{\type{bar}} + 1_{\type+}+} + 1 +
+3_{\type{foo}} = 14$ tokens.
+
+A control sequence normally starts with a backslash. Some are built in, these are
+called primitives, and others are defined by the macro package or the user. There
+is a lookup table that relates the tokenized control sequence to some action. For
+instance:
+
+\starttyping
+\def\foo{foo}
+\stoptyping
+
+creates an entry that leads (directly or following a hash chain) to the three
+letter token list. Every time the input sees \type {\foo} it gets resolved to
+that list via a hash lookup. However, once internalized and part of a token list,
+it is a direct reference. On the other hand,
+
+\starttyping
+\the\count0
+\stoptyping
+
+triggers the \type {\the} action that relates to this control sequence, which
+then reads a next token and operates on that. That next token itself expects a
+number as follow up. In the end the value of \type {\count0} is found and that
+one is also in the so called equivalent lookup table, in what \TEX\ calls
+specific regions.
+
+\starttyping
+equivalents = {
+ { level, type, value },
+ { level, type, value },
+ { level, type, value },
+ ...
+}
+\stoptyping
+
+The value is in most cases similar to the info (cmd & chr) field in fixmem, but
+one difference is that counters, dimensions etc directly store their value, which
+is why we sometimes need the type separately, for instance in order to reclaim
+memory for glue or node specifications. It sound complicated and it is, but as
+long as you get a rough idea we can continue. Just keep in mind that tokens
+sometimes get expanded on the fly, and sometimes just get stored.
+
+There are a lot of primitives and each has a unique info. The same is true for
+characters (each category has its own command code, so regular letters can be
+distinguished from other tokens, comment signs, math triggers etc). All important
+basic bits are in table of equivalents: macros as well as registers although the
+meaning of a macro and content of token lists lives in the fixmem table and
+the content of boxes in so called node lists (nodes have their own memory).
+
+In traditional \TEX\ the lookup table for primitives, registers and macros is as
+compact as can be: it is an array of so called 32 bit memory words. These can be
+divided into halfs and quarters, so in the source you find terms like \type
+{halfword} and \type {quarterword}. The lookup table is a hybrid:
+
+\starttyping
+[level 8] [type 8] [value 16] | [equivalent 32]
+[level 8] [type 8] [value 16] | [equivalent 32]
+[level 8] [type 8] [value 16] | [equivalent 32]
+...
+\stoptyping
+
+The mentioned counters and such are directly encoded in an equivalent and the
+rest is a combination of level, type and value. The level is used for the
+grouping, and in for instance \PDFTEX\ there can therefore be at most 255 levels.
+In \LUATEX\ we use a wider model. There we have 64 bit memory words which means
+that we have way more levels and don't need to have this dual nature:
+
+\starttyping
+[level 16] [type 16] [value 32]
+[level 16] [type 16] [value 32]
+[level 16] [type 16] [value 32]
+...
+\stoptyping
+
+We already showed a \LUA\ representation. The type in this table is what a
+command code is in an \quote {info} field. In such a token the integer encodes
+the command as well as a value (called chr). In the lookup table the type is the
+command code. When \TEX\ is dealing with a control sequences it looks at the
+type, otherwise it filters the command from the token integer. This means that a
+token cannot store an integer (or dimension), but the lookup table actually can
+do that. However, commands can limit the range, for instance characters are bound
+by what \UNICODE\ permits.
+
+Internally, \LUATEX\ still uses these ranges of fast accessible registers, like
+counters, dimensions and attributes. However, we saw that in \LUATEX\ they don't
+overlap with the level and type. In \LUATEX, at least till version 1.13 we still
+have the shadow array for levels but in \LUAMETATEX\ we just use those in the
+equivalents lookup table. If you look in the \PASCAL\ source you will notice that
+arrays run from \type {[somemin ... somemax]} which in the \CCODE\ source would
+mean using offsets. Actually, the shadow array starts at zero so we waste the
+part that doesn't need shadowing. It is good to remind ourselves that traditional
+\TEX\ is 8 bit character based.
+
+The equivalents lookup table has all kind of special ranges (combined into
+regions of similar nature, in \TEX\ speak), like those for lowercase mapping,
+specific catcode mappings, etc.\ but we're still talking of $n \times 256$
+entries. In \LUATEX\ all these mappings are in dedicated sparse hash tables
+because we need to support the full \UNICODE\ repertoire. This means that, while
+on the one hand \LUATEX\ uses more memory for the lookup table the number of
+slots can be less. But still there was the waste of the shadow level table: I
+didn't calculate the exact saving of ditching that one, but I bet it came close
+to what was available as total memory for programs and data on the first machines
+that I used for running \TEX. But \unknown\ after more than a decade of \LUATEX\
+we now reclaimed that space in \LUAMETATEX. \footnote {Don't expect a gain in
+performance, although using less memory might pay back on a virtual machine or
+when \TEX\ has to share the \CPU\ cache.}
+
+Now, in case you're interested (and actually I just write it down because I don't
+want to forget it myself) the lookup table in \LUAMETATEX\ is layout as follows
+
+\starttabulate
+\NC the hash table \NC \NC \NR
+\NC some frozen primitives \NC \NC \NR
+\NC current and defined fonts \NC one slot + many pointers \NC \NR
+\NC undefined control sequence \NC one slot \NC \NR
+\NC internal and register glue \NC pointer to node \NC \NR
+\NC internal and register muglue \NC pointer to node \NC \NR
+\NC internal and register toks \NC pointer to token list \NC \NR
+\NC internal and register boxes \NC pointer to node list \NC \NR
+\NC internal and register counts \NC value in token \NC \NR
+\NC internal and register attributes \NC value in token \NC \NR
+\NC internal and register dimens \NC value in token \NC \NR
+\NC some special data structures \NC pointer to node list \NC \NC \NR
+\NC the (runtime) extended hash table \NC \NC \NR
+\stoptabulate
+
+Normally a user doesn't need to know anything about these specific properties of
+the engine and it might comfort you to know that for a long time I could stay
+away from these details. One difference with the other engines is that we have
+internal variables and registers split more explicitly. The special data
+structures have their own slots and are not just put somewhere (semi random). The
+initialization is bit more granular in that we properly set the types (cmd codes)
+for registers which in turn is possible because for instance we're able to
+distinguish glue types. This is all part of coming up with a bit more consistent
+interface to tokens from the \LUA\ end. It also permits diagnostics.
+
+Anyway, we now are ready for some more details about tokens. You don't need to
+understand all of it in order to define decent macros. But when you are using
+\LUATEX\ and do want to mess around here is some insight. Assume we have defined
+these macros:
+
+\startluacode
+ local alsoraw = false
+ function documentdata.StartShowTokens(rawtoo)
+ context.starttabulate { "|T|rT|lT|rT|rT|rT|" .. (rawtoo and "rT|" or "") }
+ context.BC()
+ context.BC() context("cmd")
+ context.BC() context("name")
+ context.BC() context("chr")
+ context.BC() context("cs")
+ if rawtoo then
+ context.BC() context("rawchr")
+ end
+ context.BC() context.NR()
+ context.SL()
+ alsoraw = rawtoo
+ end
+ function documentdata.StopShowTokens()
+ context.stoptabulate()
+ end
+ function documentdata.ShowToken(name)
+ local cmd, chr, cs = token.get_cmdchrcs(name)
+ local _, raw, _ = token.get_cmdchrcs(name,true)
+ context.NC() context("\\string\\"..name)
+ context.NC() context(cmd)
+ context.NC() context(tokens.commands[cmd])
+ context.NC() context(chr)
+ context.NC() context(cs)
+ if alsoraw and chr ~= raw then
+ context.NC() context(raw)
+ end
+ context.NC() context.NR()
+ end
+\stopluacode
+
+\startbuffer
+\def\MacroA{a} \def\MacroB{b}
+\def\macroa{a} \def\macrob{b}
+\def\MACROa{a} \def\MACROb{b}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+How does that end up internally?
+
+\startluacode
+ documentdata.StartShowTokens(true)
+ documentdata.ShowToken("scratchcounterone")
+ documentdata.ShowToken("scratchcountertwo")
+ documentdata.ShowToken("scratchdimen")
+ documentdata.ShowToken("scratchtoks")
+ documentdata.ShowToken("scratchcounter")
+ documentdata.ShowToken("letterpercent")
+ documentdata.ShowToken("everypar")
+ documentdata.ShowToken("%")
+ documentdata.ShowToken("pagegoal")
+ documentdata.ShowToken("pagetotal")
+ documentdata.ShowToken("hangindent")
+ documentdata.ShowToken("hangafter")
+ documentdata.ShowToken("dimdim")
+ documentdata.ShowToken("relax")
+ documentdata.ShowToken("dimen")
+ documentdata.ShowToken("stoptext")
+ documentdata.ShowToken("MacroA")
+ documentdata.ShowToken("MacroB")
+ documentdata.ShowToken("MacroC")
+ documentdata.ShowToken("macroa")
+ documentdata.ShowToken("macrob")
+ documentdata.ShowToken("macroc")
+ documentdata.ShowToken("MACROa")
+ documentdata.ShowToken("MACROb")
+ documentdata.ShowToken("MACROc")
+ documentdata.StopShowTokens()
+\stopluacode
+
+We show the raw chr value but in the \LUA\ interface these are normalized to for
+instance proper register indices. This is because the raw numbers can for
+instance be indices into memory or some \UNICODE\ reference with catcode specific
+bits set. But, while these indices are real and stable, these offsets can
+actually change when the implementation changes. For that reason, in \LUAMETATEX\
+we can better talk of command codes as main indicator and:
+
+\starttabulate
+\NC subcommand \NC for tokens that have variants, like \type {\ifnum} \NC \NR
+\NC register indices \NC for the 64K register banks, like \type {\count0} \NC \NR
+\NC internal indices \NC for internal variables like \type {\parindent} \NC \NR
+\NC characters \NC specific \UNICODE\ slots combined with catcode \NC \NR
+\NC pointers \NC to token lists, macros, \LUA\ functions, nodes \NC \NR
+\stoptabulate
+
+This so called \type {cs} number is a pointer into the table of equivalents. That
+number results comes from the hash table. A macro name, when scanned the first
+time, is still a sequence of bytes. This sequence is used to compute a hash
+number, which is a pointer to a slot in the lower part of the hash (lookup)
+table. That slot points to a string and a next hash entry in the higher end. A
+lookup goes as follows:
+
+\startitemize[n,packed]
+ \startitem
+ compute the index into the hash table from the string
+ \stopitem
+ \startitem
+ goto the slot with that index and compare the \type {string} field
+ \stopitem
+ \startitem
+ when there is no match goto the slot indicated by the \type {next} field
+ \stopitem
+ \startitem
+ compare again and keep following \type {next} fields till there is no
+ follow up
+ \stopitem
+ \startitem
+ optionally create a new entry
+ \stopitem
+ \startitem
+ use the index of that entry as index in the table of equivalents
+ \stopitem
+\stopitemize
+
+So, in \LUA\ speak, we have:
+
+\starttyping
+hashtable = {
+ -- lower part, accessed via the calculated hash number
+ { stringpointer, nextindex },
+ { stringpointer, nextindex },
+ ...
+ -- higher part, accessed by following nextindex
+ { stringpointer, nextindex },
+ { stringpointer, nextindex },
+ ...
+}
+\stoptyping
+
+Eventually, after following a lookup chain in the hash tabl;e, we end up at
+pointer to the equivalents lookup table that we already discussed. From then on
+we're talking tokens. When you're lucky, the list is small and you have a quick
+match. The maximum initial hash index is not that large, around 64K (double that
+in \LUAMETATEX), so in practice there will often be some indirect
+(multi|-|compare) match but increasing the lower end of the hash table might
+result in less string comparisons later on, but also increases the time to
+calculate the initial hash needed for accessing the lower part. Here you can sort
+of see that:
+
+\startbuffer
+\dostepwiserecurse{`a}{`z}{1}{
+ \expandafter\def\csname whatever\Uchar#1\endcsname
+ {}
+}
+\dostepwiserecurse{`a}{`z}{1}{
+ \expandafter\let\csname somemore\Uchar#1\expandafter\endcsname
+ \csname whatever\Uchar#1\endcsname
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startluacode
+ documentdata.StartShowTokens(true)
+ for i=utf.byte("a"),utf.byte("z") do
+ documentdata.ShowToken("whatever"..utf.char(i))
+ documentdata.ShowToken("somemore"..utf.char(i))
+ end
+ documentdata.StopShowTokens()
+\stopluacode
+
+The command code indicates a macro and the action related to it is an expandable
+call. We have no sub command \footnote {We cheat a little here because chr
+actually is an index into token memory but we don't show them as such.} so that
+column shows zeros. The fifth column is the hash entry which can bring us back to
+the verbose name as needed in reporting while the last column is the index to
+into token memory (watch the duplicates for \type {\let} macros: a ref count is
+kept in order to be able to manage such shared references). When you look a the
+cs column you will notice that some numbers are close which (I think) in this
+case indicates some closeness in the calculated hash name and followed chain.
+
+It will be clear that it is best to not make any assumptions with respect to the
+numbers which is why, in \LUAMETATEX\ we sort of normalize them when accessing
+properties.
+
+\starttabulate
+\NC field \NC meaning \NC \NR
+\FL
+\NC command \NC operator \NC \NR
+\NC cmdname \NC internal name of operator \NC \NR
+\NC index \NC sanitized operand \NC \NR
+\NC mode \NC original operand \NC \NR
+\NC csname \NC associated name \NC \NR
+\NC id \NC the index in token memory (a virtual address) \NC \NR
+\NC tok \NC the integer representation \NC \NR
+\ML
+\NC active \NC true when an active character \NC \NR
+\NC expandable \NC true when expandable command \NC \NR
+\NC protected \NC true when a protected command \NC \NR
+\NC frozen \NC true when a frozen command \NC \NR
+\NC user \NC true when a user defined command \NC \NR
+\LL
+\stoptabulate
+
+When a control sequence is an alias to an existing primitive, for instance
+made by \type {\let}, the operand (chr) picked up from its meaning. Take this:
+
+\startbuffer
+\newif\ifmyconditionone
+\newif\ifmyconditiontwo
+
+ \meaning\ifmyconditionone \crlf
+ \meaning\ifmyconditiontwo \crlf
+ \meaning\myconditiononetrue \crlf
+ \meaning\myconditiontwofalse \crlf
+\myconditiononetrue \meaning\ifmyconditionone \crlf
+\myconditiontwofalse\meaning\ifmyconditiontwo \crlf
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Internally this is:
+
+\startluacode
+ documentdata.StartShowTokens(false)
+ documentdata.ShowToken("ifmyconditionone")
+ documentdata.ShowToken("ifmyconditiontwo")
+ documentdata.ShowToken("iftrue")
+ documentdata.ShowToken("iffalse")
+ documentdata.StopShowTokens()
+\stopluacode
+
+The whole list of available commands is given below. Once they are stable the \LUAMETATEX\ manual
+will document the accessors. In this chapter we use:
+
+\starttyping
+kind, min, max, fixedvalue token.get_range("primitive")
+cmd, chr, cs = token.get_cmdchrcs("primitive")
+\stoptyping
+
+The kind of command is given in the first column, which can have the following values:
+
+\starttabulate[|l|l|p|]
+\NC 0 \NC no \NC not accessible \NC \NR
+\NC 1 \NC regular \NC possibly with subcommand \NC \NR
+\NC 2 \NC character \NC the \UNICODE\ slot is encodes in the the token \NC \NR
+\NC 3 \NC register \NC this is an indexed register (zero upto 64K) \NC \NR
+\NC 4 \NC internal \NC this is an internal register (range given) \NC \NR
+\NC 5 \NC reference \NC this is a reference to a node, \LUA\ function, etc. \NC \NR
+\NC 6 \NC data \NC a general data entry (kind of private) \NC \NR
+\NC 7 \NC token \NC a token reference (that can have a followup) \NC \NR
+\stoptabulate
+
+\usemodule[system-tokens]
+
+\start \switchtobodyfont[7pt] \showsystemtokens \stop
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore.tex b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore.tex
index 293753a797c..b351e8c681a 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore.tex
@@ -20,6 +20,24 @@
\component evenmore-macros
\component evenmore-libraries
\component evenmore-whattex
+ \component evenmore-numbers
+ \component evenmore-parameters
+ \component evenmore-parsing
+ \component evenmore-tokens
+ \component evenmore-keywords
+
+ \startchapter[title=Paragraphs] {\em This chapter is not yet public.} \stopchapter
+ \startchapter[title=Hyphenation] {\em This chapter is not yet public.} \stopchapter
+ \startchapter[title=Bitwise] {\em This chapter is not yet public.} \stopchapter
+ \startchapter[title=Offloading] {\em This chapter is not yet public.} \stopchapter
+ \startchapter[title=Inserts] {\em This chapter is not yet public.} \stopchapter
+
+ % \component evenmore-paragraphs
+ % \component evenmore-hyphenation
+ % \component evenmore-bitwise
+ % \component evenmore-offloading
+ % \component evenmore-inserts
+
\stopbodymatter
\stopdocument
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-compilation.tex b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-compilation.tex
index a0e67d4bed9..9e4b10662ba 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-compilation.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-compilation.tex
@@ -4,6 +4,12 @@
\environment followingup-style
+\logo[WLS] {WLS}
+\logo[INTEL] {Intel}
+\logo[APPLE] {Apple}
+\logo[UBUNTU] {Ubuntu}
+\logo[RASPBERRY] {RaspberryPi}
+
\startchapter[title={Compilation}]
Compiling \LUATEX\ is possible because after all it's what I do on my machine.
@@ -50,7 +56,7 @@ In retrospect I should have done that sooner because in a day I could get all
relevant platforms working. Flattening the source tree was a next step and so
there is no way back now. What baffled me (and Alan, who at some point joined in
testing \OSX) is the speed of compilation. My pretty old laptop needed about half
-a minute to get the job done and even on a raspberry pi with only a flash card
+a minute to get the job done and even on a \RASPBERRY\ with only a flash card
just a few minutes were needed. At that point, as we could remove more make
related files, the compressed 11 MB archive (\type {tar.xz}) shrunk to just over
2~MB. Interesting is that compiling \MPLIB\ takes most time, and when one compiles
@@ -79,6 +85,69 @@ equivalent for zero was made a bit more distinctive as we now have more subtypes
That is: all the subtypes were collected in enumerations instead of \CCODE\
defines. Back to the basics.
+End of 2020 I noticed that the binary had grown a bit relative to the mid 2020
+versions. This surprised me because some improvements actually made them smaller,
+something you notice when you compile a couple of times when doing these things.
+I also noticed that the platforms on the compile farm had quite a bit of
+variation. In most cases we're still below my 3MB threshold, but when for
+instance cross compiled binaries become a few hundred MB larger one can get
+puzzled. In the \LUAMETAFUN\ manual I have this comment at the top:
+
+\starttyping[style=\ttx]
+------------------------ ------------------------ ------------------------
+2019-12-17 32bit 64bit 2020-01-10 32bit 64bit 2020-11-30 32bit 64bit
+------------------------ ------------------------ ------------------------
+freebsd 2270k 2662k freebsd 2186k 2558k freebsd 2108k 2436k
+openbsd6.6 2569k 2824k openbsd6.6 2472k 2722k openbsd6.8 2411k 2782k
+linux-armhf 2134k linux-armhf 2063k linux-armhf 2138k 2860k
+linux 2927k 2728k linux 2804k 2613k linux (?) 3314k 2762k
+ linux-musl 2532k 2686k
+osx 2821k osx 2732k osx 2711k
+ms mingw 2562k 2555k ms mingw 2481k 2471k ms mingw 2754k 2760k
+ ms intel 2448k
+ ms arm 3894k
+ ms clang 2159k
+------------------------ ------------------------ ------------------------
+\stoptyping
+
+So why the differences? One possible answer is that the cross compiler now uses
+\GCC9 instead of \GCC8. It is quite likely that inlining code is done more
+aggressively (at least one can find remarks of that kind on the Internet). An
+interesting exception in this overview is the \LINUX\ 32 bit version. The native
+\WINDOWS\ binary is smaller than the \MINGW\ binary but the \CLANG\ variant is
+still smaller. For the native compilation we always enabled link time
+optimization, which makes compiling a bit slower but similar to regular
+compilation in \WLS\ but when for the other compilers we turn on link time
+optimization the linker takes quite some time. I just turn it off when testing
+code because it's no fun to wait these additional minutes with \GCC. Given that
+the native windows binary by now runs nearly as fast as the cross compiled ones,
+it is an indication that the native \WINDOWS\ compiler is quite okay. The numbers
+also show (for \WINDOWS) that using \CLANG\ is not yet an option: the binaries
+are smaller but also much slower and compilation (without link time optimization)
+also takes much longer. But we'll see how that evolves: the compile farm
+generates them all.
+
+So, what effects does link time optimization has? The (current) cross compiled
+binary is is some 60KB smaller and performs a little better. Some tests show
+some 3~percent gain but I'm pretty sure users won't notice that on a normal run.
+So, when we forget to enable it when we release new binaries, it's no big deal.
+
+Another end 2020 adventure was generating \ARM\ binaries for \OSX\ and \WINDOWS.
+This seems to work out well. The \OSX\ binaries were tested, but we don't have
+the proper hardware in the compile farm, so for now users have to use \INTEL\
+binaries on that hardware. Compiling the \LUAMETATEX\ manual on a 2020 M1 is a
+little more that twice as fast than on my 2013 i7 laptop running \WINDOWS. A
+native \ARM\ binary is about three times faster, which is what one expects from a
+more modern (also a bit performance hyped) chipset. On a \RASPBERRY\ with 4MB
+ram, an external \SSD\ on \USB3, running \UBUNTU\ 20, the manual compiles three
+times slower than on my laptop. So, when we limit conclusions to \LUAMETATEX\ it
+looks like \ARM\ is catching up: these modern chipsets (from \APPLE\ and
+\MICROSOFT, although the later was not yet tested) with plenty of cache, lots of
+fast memory, fast graphics and speedy disks are six times faster than a cheap
+media oriented \ARM\ chipset. Being a single core consumer, \LUAMETATEX\ benefits
+more from faster cores than from more cores. But, unless I have these machines
+on my desk these rough estimates have to do.
+
\stopchapter
\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
new file mode 100644
index 00000000000..502370d7db1
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
@@ -0,0 +1,711 @@
+% language=us
+
+\startcomponent followingup-fonts
+
+\environment followingup-style
+
+\startchapter[title={Scaled fonts}]
+
+\startsection[title={History}]
+
+The infrastructure for fonts makes up a large part of the code of any \TEX\ macro
+package. We have to go back in time to understand why. When \TEX\ showed up,
+fonts were collections of bitmaps and measures. There were at most 256 glyphs in
+a font and in order to do its job, \TEX\ needed to know (and still needs to know)
+the width, height and depth of glyphs. If you want ligatures it also needs to
+know how to construct them from the input and when you want kerning there has to
+be additional information about what neighboring glyphs need a kern in between.
+Math is yet another subtask that demands extra information, like chains of glyphs
+that grow in size and if needed even recipes of how to construct large shapes
+from smaller ones.
+
+Fonts come in sizes. Latin Modern and the original Computer Modern, for instance,
+have quite a few variants where the shapes are adapted to the size. This means
+that when you need a 9pt regular shape alongside a 12pt one, two fonts have to be
+loaded. This is quite visible in math where we have three related sizes: text,
+script and scriptscript, grouped in so called families. When we scale the digit~2
+to the same height you will notice that the text, script and scriptscript sizes
+look different (the last three are unscaled):
+
+\startlinecorrection
+\dontleavehmode\scale[frame=on,height=5ex]{$\textstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=5ex]{$\scriptstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=5ex]{$\scriptscriptstyle 2$}\quad\quad
+\dontleavehmode\scale[frame=on,height=2ex]{$\textstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=2ex]{$\scriptstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=2ex]{$\scriptscriptstyle 2$}\quad\quad
+\dontleavehmode\scale[frame=on,width=4em]{\colored[r=.6,a=1,t=.5]{$\textstyle 2$}}\hskip-4em
+\dontleavehmode\scale[frame=on,width=4em]{\colored[g=.6,a=1,t=.5]{$\scriptstyle 2$}}\hskip-4em
+\dontleavehmode\scale[frame=on,width=4em]{\colored[b=.6,a=1,t=.5]{$\scriptscriptstyle 2$}}\quad\quad
+\dontleavehmode{$\textstyle 2$}\quad
+\dontleavehmode{$\scriptstyle 2$}\quad
+\dontleavehmode{$\scriptscriptstyle 2$}\quad
+\stoplinecorrection
+
+Plenty has been written (in various documents that come with \CONTEXT) about how
+this all works together and how it impacts the design of the system, so here I
+just give a short summary of what a font system has to deal with.
+
+\startitemize
+\startitem
+ In a bodyfont setup different sizes (9pt, 10pt, 12pt) can have their own
+ specific set of fonts. This can result in quite a number of definitions that
+ relate to the style, like regular, bold, italic, bold italic, slanted, bold
+ slanted, etc. When possible loading the fonts is delayed. In \CONTEXT\ often
+ the number of fonts that are actually loaded is not that large.
+\stopitem
+\startitem
+ Some font designs have different shapes per bodyfont size. A minor
+ complication is that when one is missing some heuristic best|-|match choice
+ might be needed. Okay, in practice only Latin Modern falls into this category
+ for \CONTEXT. Maybe \OPENTYPE\ variable fonts can be seen this way, but,
+ although we supported that right from the start, I haven't noticed much
+ interest in the \TEX\ community.
+\stopitem
+\startitem
+ Within a bodyfont size we distinguish size variants. We can go smaller (x and
+ xx), for instance when we use sub- and superscripts in text, or we can go
+ larger, for instance in titles (a, b, c, d, \unknown). Fortunately most of
+ the loading of these can be delayed too.
+\stopitem
+\startitem
+ When instances are not available, scaling can be used, as happens for
+ instance with 11pt in Computer Modern. Actually, this is why in \CONTEXT\ we
+ default to 12pt, because the scaled versions didn't look as nice as the
+ others (keep in mind that we started in the age of bitmaps).
+\stopitem
+\startitem
+ Special features, such as smallcaps or oldstyle numerals, can demand their own
+ definitions. More loading and automatic definitions can be triggered by sizes
+ needed in, e.g., scripts and titles.
+\stopitem
+\startitem
+ A document can have a mixed setup, that is: using different font
+ designs within one
+ document, so some kind of namespace subsystem is needed.
+\stopitem
+\startitem
+ In an eight|-|bit font world, we not only have text fonts but also collections
+ of symbols, and even in math there are additional symbol collections. In
+ \OPENTYPE\ symbols end up in text fonts, but there we have tons of emojis
+ and color fonts. All has to be dealt with in an integrated way. And we're
+ not even talking of virtual fonts, (runtime) \METAPOST\ generated fonts, and
+ so on.
+\stopitem
+\startitem
+ In traditional eight|-|bit engines, hyphenation depends on a font's encoding,
+ which can require loading a font multiple times in different encodings. This
+ depends on the language mix used. A side point is that defining a European
+ encoding covering most Latin languages was not that hard, especially when one
+ keeps in mind that many eight|-|bit encodings waste slots on seldom used
+ symbols, but by that time \OPENTYPE\ and \UNICODE\ input started to dominate.
+\stopitem
+\startitem
+ In the more modern \OPENTYPE\ fonts combinations of features can demand
+ additional instances: one can think of language|/|script combinations,
+ substitutions in base mode, special effects like emboldening, color fonts,
+ etc.
+\stopitem
+\startitem
+ Math is complicated by the fact that in traditional \TEX, alphabets come from
+ different fonts, which is why we have many so|-|called families; a font can
+ have several alphabets which means that some mapping can be needed. Operating
+ on the size, shape, encoding and style axes puts some demands on the font
+ system. Add to this the (often) partial (due to lack of fonts) bold support
+ and it gets even more complicated. In \OPENTYPE\ all the alphabets come from
+ one font.
+\stopitem
+\startitem
+ There is additional math auto|-|definition and loading code for the sizes
+ used in text scripts and titles.
+\stopitem
+\stopitemize
+
+All this has resulted in a pretty complex subsystem. Although going \OPENTYPE\
+(and emulated \OPENTYPE\ with \TYPEONE\ fonts as we do in \MKIV) removes some
+complications, like encodings, it also adds complexity because of the many
+possible font features, either dependent or not on script and language. Text as
+well as math got simpler in the \TEX\ code, though that was traded for quite a
+bit of \LUA\ code to deal with new features.
+
+So, in order to let the font subsystem not impact performance too much, let alone
+extensive memory usage, the \CONTEXT\ font subsystem is rather optimized. The
+biggest burden comes from fonts that have a dynamic (adaptive) definition because
+then we need to do quite a bit of testing per font switch, but even that has
+always been rather fast.
+
+\stopsection
+
+\startsection[title={Reality}]
+
+In \MKIV\ and therefore also in \LUAMETATEX\ (\LMTX) more font magic happens. The
+initial node lists that make up a box or paragraph can get manipulated in several
+ways and often fonts are involved. The font features (smallcaps, oldstyle,
+alternates, etc.)\ can be defined as static (part of the definition) or as
+dynamic (resolved on the spot at the cost of some overhead). Characters can be
+remapped, fonts can be replaced. The math subsystem in \MKIV\ was different right
+from the start: we use a limited number of families (regular, bold, l2r and r2l),
+and stay abstract till the moment we need to deal with the specific alphabets.
+But still, in \MKIV, we have the families with three fonts.
+
+In the \LUAMETATEX\ manual we show some math magic for different fonts. As a side
+effect, we set up half a dozen bodyfont collections: Lucida, Pagella, Latin
+Modern, Dejavu, the math standard Cambria, etc. Even with delayed and shared font
+loading, we end up with 158 instances but quite a few of them are math fonts, at
+least six per bodyfont size: regular and bold (emboldened) text, script and
+scriptscript. Of course most are just copies with different scaling that reuse
+already loaded resources. In the final \PDF\ we have 21 subsetted fonts.
+
+If we look at the math fonts that we use today, there is however quite some
+overlap. It starts with a text font. From that, script and scriptscript variants
+are derived, but often these variants use many text size related shapes too. Some
+shapes get alternatives (from the \type {ssty} feature), and the whole clone gets
+scaled. But, much of the logic of, for instance, extensibles is the same.
+
+A similar situation happens with large \CJK\ fonts: there are hardly any advanced
+features involved there, so any size is basically a copy with scaled dimensions,
+and these fonts can be truly huge!
+
+When we talk about features, in many cases in \CONTEXT\ you don't define them as
+part of the font. For instance small caps can best be triggered by using a
+dynamic feature: applied to a specific stretch of text. In fact, often features
+like superiors of fractions only work well on characters that fit the bill and
+produce weird side effects otherwise (a matter of design completeness). When the
+font handler does its work there are actually four cases: no features get applied
+(something that happens with, for instance, most monospaced fonts); base mode is
+used (which means that the \TEX\ machinery takes care of constructing ligatures
+and injecting kerns); and node mode (where \LUA\ handles the features). The
+fourth case is a special case of node mode where a different feature set is
+applied. \footnote {We also have so|-|called plug mode where an external renderer
+can do the work but that one is only around due to some experiments during Idris
+Hamid's font development.} At the cost of some extra overhead (for each node mode
+run) dynamic features are quite powerful and save quite a lot of memory and
+definitions. \footnote {The generic font handler that is derived from the
+\CONTEXT\ one doesn't implement this, so it runs a little faster.} The overhead
+comes from much more testing regarding the font we deal with because suddenly the
+same font can demand different treatments, depending on what dynamic features are
+active. \footnote {Originally this model was introduced for a dynamic paragraph
+optimization subsystem for Arabic but in practice no one uses it because there
+are no suitable fonts.}
+
+Although the font handling is responsible for much of the time spent in \LUA, it
+is still reasonable given what has to be done. Because we have an extensible
+system, it's often the extensions that takes additional runtime. Flexibility
+comes at a price.
+
+\stopsection
+
+\startsection[title={Progress}]
+
+At some point I started playing with realtime glyph scaling. Here realtime means
+that it doesn't depend on the font definition. To get an idea, here is an example
+(all examples are additionally scaled for \TUGBOAT):
+
+\startbuffer
+test {\glyphxscale 2500 test} test
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+The glyphs in the current font get scaled horizontally without the need for an
+extra font instance. Now, this kind of trickery puts some constraints on the font
+handling, as is demonstrated in the next example. We use Latin Modern because
+that font has all these ligatures:
+
+\startbuffer
+\definedfont[lmroman10-regular*default]%
+e{\glyphxscale 2500 ff}icient
+ef{\glyphxscale 2500 f}icient
+ef{\glyphxscale 2500 fi}cient
+e{\glyphxscale 2500 ffi}cient
+\stopbuffer
+
+\typebuffer
+
+{\getbuffer}
+
+In order to deal with this kind of scaling, we now operate not only on the font
+(id) and dynamic feature axes, but also on the scales, of which we have three
+variants: glyph scale, glyph xscale and glyph yscale. There is actually also a
+state dimension but we omit that for now (think of flagging glyphs as initial or
+final). This brings the number of axis to six. It is important to stress that in
+these examples the same font instance is used!
+
+Just for the record: several approaches to switching fonts are possible but for
+now we stick to a simple font id switch plus glyph scale settings at the \TEX\
+end. A variant would be to introduce a new mechanism where id's and scales go
+together but for now I see no real gain in that.
+
+\stopsection
+
+\startsection[title={Math}]
+
+Given what has been discussed in the previous sections, a logical question would
+be \quotation {Can we apply scaling to math?} and the answer is \quotation {Yes,
+we can!}. We can even go a bit further and that is partly due to some other
+properties of the engine.
+
+From \PDFTEX\ the \LUATEX\ engines inherited character protrusion and glyph
+expansions, aka hz. However, where in \PDFTEX\ copies of the font are made that
+carry the expanded dimensions, in \LUATEX\ at some point this was replaced by an
+expansion field in the glyph and kern nodes. So, instead of changing the font id
+of expanded glyphs, the same id is used but with the applied expansion factor set
+in the glyph. A side effect was that in places where dimensions are needed, we
+call functions that calculate the expanded widths on request (as these can change
+during linebreak calculations) in combination with accessing font dimensions
+directly. This level of abstraction is even more present in \LUAMETATEX. This
+means that we have an uniform interface to fonts and as a side effect scaling
+need be dealt with in only a few places in the code.
+
+Now, in math we have a few more complications. First of all, we have three sizes
+to consider and we also have lots of parameters that depend on the size. But, as
+I wanted to be able to apply scaling to math, the whole machinery was also
+abstracted in a way that, at the cost of some extra overhead, made it easier to
+work with scaled glyph properties. This means that we can stick to loading only
+one bodyfont size of math (note that each math family has three sizes, where the
+script and script sizes can have different, fine tuned, shapes) and just scale
+that on demand.
+
+Once all that was in place it was a logical next step to see if we could stick to
+just a single instance. Because in \LUAMETATEX\ we try to load fonts efficiently
+we store only the minimally needed information at the \TEX\ end. A font with no
+math therefore has less data per glyph. Again, this brings some abstraction that
+helped to implement the one instance mechanism. A math glyph has optional lists
+of increasing sizes and vertical or horizontal extensibles. So what got added was
+an optional chain of smaller sizes. If a character has three different glyphs for
+the three sizes, the text glyph has a pointer to the script glyph which in turn
+has a pointer to the scriptscript glyph. This means that when the math engine
+needs a specific character at a given size (text, script, scriptscript) we just
+follow that chain.
+
+In an \OPENTYPE\ math font the script and scriptscript sizes are specified as
+percentages of the text size. When the dimensions of a glyph are needed, we just
+scale on the fly. Again this adds some overhead but I'm pretty sure that no user
+will notice.
+
+So, to summarize: if we need a character at scriptscript size, we access the text
+size glyph, check for a pointer to a script size, go there, and again check for a
+smaller size. We use only what fits the bill. And, when we need dimensions we
+just scale. In order to scale we need the relative size, so we need to set that
+up when we load the font. Because in \CONTEXT\ we also can assemble a virtual
+\OPENTYPE\ font from \TYPEONE\ fonts, it was actually that (old) compatibility
+feature, the one that implements \TYPEONE\ based on \OPENTYPE\ math, that took
+the most time to adapt, not so much because it is complicated but because in
+\LMTX\ we have to bypass some advanced loading mechanisms. Because we can scale
+in two dimensions the many (font|-|related) math parameters also need to be dealt
+with accordingly.
+
+The end result is that for math we now only need to define two fonts per bodyfont
+setup: regular and bold at the natural scale (normally 10pt) and we share these
+for all sizes. As a result of this and what we describe in the next section, the
+158 instances for the \LUAMETATEX\ manual can be reduced to~30.
+
+
+\stopsection
+
+\startsection[title={Text}]
+
+Sharing instances in text mode is relatively simple, although we do have to keep
+in mind that scaling is an extra axis when dealing with font features: two
+neighboring glyphs with the same font id and dynamics but with different scales
+are effectively from different fonts.
+
+Another complication is that when we use font fallbacks (read:\ take missing
+glyphs from another font) we no longer have a dedicated instance but use a shared
+one. This in itself is not a problem but we do need to handle specified relative
+scales. This was not that hard to patch in \CONTEXT\ \LMTX.
+
+We can enforce aggressive font sharing with:
+
+\starttyping
+\enableexperiments[fonts.compact]
+\stoptyping
+
+After that we often use fewer instances. Just to give an idea, on the \LUAMETATEX\
+manual we get these stats:
+
+\starttyping
+290 pages, 10.8 sec, 292M lua, 99M tex, 158 instances
+290 pages, 9.5 sec, 149M lua, 35M tex, 30 instances
+\stoptyping
+
+So, we win on all fronts when we use this glyph scaling mechanism. The magic
+primitive that deals with this is named \type {\glyphscale}; it accepts a
+number, where \type {1200} and \type {1.2} both mean scaling to 20\percent\ more
+than normal. But it's best not to use this primitive directly.
+
+A specific scaled font can be defined using the \type {\definefont} command. In
+\LMTX\ a regular scaler can be followed by two scale factors. The next example
+demonstrates this (as can be seen, the \type {yoffset} affects the baseline):
+
+\startbuffer
+\definefont[FooA][Serif*default @ 12pt 1800 500]
+\definefont[FooB][Serif*default @ 12pt 0.85 0.4]
+\definefont[FooC][Serif*default @ 12pt]
+
+\definetweakedfont[runwider] [xscale=1.5]
+\definetweakedfont[runtaller][yscale=2.5,xscale=.8,yoffset=-.2ex]
+
+{\FooA test test \runwider test test \runtaller test test}\par
+{\FooB test test \runwider test test \runtaller test test}\par
+{\FooC test test \runwider test test \runtaller test test}\par
+\stopbuffer
+
+\typebuffer
+
+We also use the new \type {\definetweakedfont} command here. This example not
+only shows the two scales but also introduces the offset.
+
+\getbuffer
+
+In compact mode this is one font. Here is another example:
+
+\startbuffer
+\definetweakedfont[squeezed][xscale=0.9]
+
+\startlines
+$a = b^2 + \sqrt{c}$
+{\squeezed $a = b^2 + \sqrt{c}$}
+\stoplines
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Watch this:
+
+\startbuffer
+\startcombination[3*1]
+ {\bTABLE
+ \bTR \bTD foo \eTD \bTD[style=\squeezed] $x = 1$ \eTD \eTR
+ \bTR \bTD oof \eTD \bTD[style=\squeezed] $x = 2$ \eTD \eTR
+ \eTABLE}
+ {local}
+ {\bTABLE[style=\squeezed]
+ \bTR \bTD $x = 1$ \eTD \bTD $x = 3$ \eTD \eTR
+ \bTR \bTD $x = 2$ \eTD \bTD $x = 4$ \eTD \eTR
+ \eTABLE}
+ {global}
+ {\bTABLE[style=\squeezed\squeezed]
+ \bTR \bTD $x = 1$ \eTD \bTD $x = 3$ \eTD \eTR
+ \bTR \bTD $x = 2$ \eTD \bTD $x = 4$ \eTD \eTR
+ \eTABLE}
+ {multiple}
+\stopcombination
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+An additional style parameter is also honored:
+
+\startbuffer
+\definetweakedfont[MyLargerFontA][scale=2000,style=bold]
+test {\MyLargerFontA test} test
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+\getbuffer
+
+Just for the record: the Latin Modern fonts, when set up to use design sizes,
+will still use the specific size|-|related files.
+
+\stopsection
+
+\startsection[title={Hackery}]
+
+You can use negative scale values, as is demonstrated in the following
+code:
+
+\startbuffer
+\bTABLE[align=middle]
+ \bTR
+ \bTD a{\glyphxscale 1000 \glyphyscale 1000 bc}d \eTD
+ \bTD a{\glyphxscale 1000 \glyphyscale -1000 bc}d \eTD
+ \bTD a{\glyphxscale -1000 \glyphyscale -1000 bc}d \eTD
+ \bTD a{\glyphxscale -1000 \glyphyscale 1000 bc}d \eTD
+ \eTR
+ \bTR
+ \bTD \tttf +1000 +1000 \eTD
+ \bTD \tttf +1000 -1000 \eTD
+ \bTD \tttf -1000 -1000 \eTD
+ \bTD \tttf -1000 +1000 \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+\typebuffer
+
+gives:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Glyphs can have offsets and these are used for implementing \OPENTYPE\ features.
+However, they are also available on the \TEX\ side. Take this example where we
+use the new \type {\glyph} primitive (a variant of \type {\char} that takes
+keywords):
+
+\startbuffer
+\ruledhbox{
+ \ruledhbox{\glyph yoffset 1ex options 0 123} % left curly brace
+ \ruledhbox{\glyph xoffset .5em yoffset 1ex options "C0 123}
+ \ruledhbox{oeps{\glyphyoffset 1ex \glyphxscale 800
+ \glyphyscale\glyphxscale oeps}oeps}
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This example demonstrates that the \type {\glyph} primitive takes quite a few
+keywords: \type {xoffset}, \type {yoffset}, \type {xscale}, \type {yscale}, \type
+{left}, \type {right}, \type {raise}, \type {options}, \type {font} and \type
+{id} where the last two take a font identifier or font id (a positive number).
+For this article it's enough to know that the option indicates that glyph
+dimension should include the offset. In a moment we will see an alternative that
+doesn't need that.
+
+\startbuffer
+\samplefile{jojomayer}
+{\glyphyoffset .8ex
+ \glyphxscale 700 \glyphyscale\glyphxscale
+ \samplefile{jojomayer}}
+{\glyphyscale\numexpr3*\glyphxscale/2\relax
+ \samplefile{jojomayer}}
+{\glyphyoffset -.2ex
+ \glyphxscale 500 \glyphyscale\glyphxscale
+ \samplefile{jojomayer}}
+\samplefile{jojomayer}
+\stopbuffer
+
+\typebuffer
+
+To quote Jojo Mayer:
+
+\startnarrower
+\darkred \getbuffer
+\stopnarrower
+
+Keep in mind that this can interfere badly with font feature processing which also
+used offsets. It might often work out okay vertically, but less well horizontally.
+
+The scales, as mentioned, works with pseudo|-|scales but that is sometimes a bit
+cumbersome. This is why a special \type {\numericscale} primitive has been
+introduced.
+
+\startbuffer
+1200 : \the\numericscale1200
+1.20 : \the\numericscale1.200
+\stopbuffer
+
+\typebuffer
+
+Both these lines produce the same integer:
+
+\startlines\tttf
+\getbuffer
+\stoplines
+
+You can do strange things with these primitives but keep in mind that you can
+also waste the defaults.
+
+\startbuffer[definition]
+\def\UnKernedTeX
+ {T%
+ {\glyph xoffset -.2ex yoffset -.4ex `E}%
+ {\glyph xoffset -.4ex options "60 `X}}
+\stopbuffer
+
+\startbuffer[example]
+We use \UnKernedTeX\ and {\bf \UnKernedTeX} and {\bs \UnKernedTeX}:
+the slanted version could use some more left shifting of the E.
+\stopbuffer
+
+\typebuffer[definition,example]
+
+This gives the \TEX\ logos but of course we normally use the more official
+definitions instead.
+
+\startnarrower
+ \darkred \getbuffer[definition,example]
+\stopnarrower
+
+Because offsets are (also) used for handling font features like mark and cursive
+placement as well as special inter|-|character positioning, the above is
+suboptimal. Here is a better alternative:
+
+\startbuffer[definition]
+\def\UnKernedTeX
+ {T\glyph left .2ex raise -.4ex `E\glyph left .2ex `X\relax}
+\stopbuffer
+
+\typebuffer[definition]
+
+The result is the same:
+
+\startnarrower
+ \darkgreen \getbuffer[definition,example]
+\stopnarrower
+
+But anyway: don't overdo it. We have dealt with such cases for decades without
+these fancy new features. The next example shows margins in action:
+
+\startlinecorrection
+\bTABLE[align=middle,width=.33\textwidth]
+ \bTR
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise 3pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise -3pt `M}>\eTD
+ \eTR
+ \bTR[frame=off]
+ \bTD \tttf \eTD
+ \bTD \tttf raise 3pt \eTD
+ \bTD \tttf raise -3pt \eTD
+ \eTR
+ \bTR
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph right 2pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt right 2pt `M}>\eTD
+ \eTR
+ \bTR[frame=off]
+ \bTD \tttf left 3pt \eTD
+ \bTD \tttf right 2pt\eTD
+ \bTD \tttf left 3pt right 2pt\eTD
+ \eTR
+ \bTR
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left -3pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph right -2pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left -3pt right -2pt `M}>\eTD
+ \eTR
+ \bTR[frame=off]
+ \bTD \tttf left -3pt \eTD
+ \bTD \tttf right -2pt \eTD
+ \bTD \tttf left -3pt right -2pt \eTD
+ \eTR
+\eTABLE
+\stoplinecorrection
+
+Here is another way of looking at it:
+
+\startbuffer
+\glyphscale 4000
+\vl\glyph `M\vl\quad
+\vl\glyph raise .2em `M\vl\quad
+\vl\glyph left .3em `M\vl\quad
+\vl\glyph right .2em`M\vl\quad
+\vl\glyph left -.2em right -.2em`M\vl\quad
+\vl\glyph raise -.2em right .4em`M\vl
+\stopbuffer
+
+\typebuffer
+
+The raise as well as left and right margins are taken into account when calculating the
+dimensions of a glyph.
+
+{\getbuffer}
+
+
+\stopsection
+
+\startsection[title={Implementation}]
+
+Discussing the implementation in the engine makes no sense here, also because
+details might change. However, it is good to know that many properties travel
+with the glyph nodes, for instance the scales, margins, offsets, language, script
+and state properties, control over kerning, ligaturing, expansion and protrusion,
+etc. The dimensions (width, height and depth) are not stored in the glyph node
+but calculated from the font, scales and optionally the offsets and expansion
+factor. One problem is that the more clever (and nice) solutions we cook up, the
+more it might impact performance. So, I will delay some experiments till I have a
+more powerful machine.
+
+One reason for {\em not} storing the dimensions in a glyph node is that we often
+copy those nodes or change character fields in the font handler and we definitely
+don't want the wrong dimensions there. At that moment, offsets and margin fields
+don't reflect features yet, so copying them is no big deal because at that moment
+these are still zero. However, dimensions are rather character bound so every
+time a character is set, we also would have to set the dimensions. Even worse,
+when we can set them, the question arises if they were already set explicitly.
+So, this is a can of worms we're not going to open: the basic width, height and
+depth of the glyph as specified in the font is used and combined with actual
+dimensions (likely already scaled according the glyph scales) in offset and
+margin fields.
+
+Now, I have to admit that especially playing with using margins to glyphs instead
+of font kerns is more of an experiment to see what the consequences are than a
+necessity, but what would be the joy of \TEX\ without such experiments? And as
+usual, in \CONTEXT\ these will become options in the font handler that one can
+enable, or not.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
+
+% sample file
+
+\setuplayout[topspace=1cm,header=1cm] \setuplayout[middle]
+
+\setupbodyfont[pagella,10pt]
+
+\setupalign[verytolerant,stretch]
+
+\setupwhitespace[big]
+
+\starttext
+
+\startbuffer
+\definetweakedfont[bfe][xscale=2000,yscale=6000,style=bf]
+
+\setuphead[chapter][style=\bfe]
+
+\dostepwiserecurse {10} {2020} {10} {
+ \title{Here we go #1!}
+ \start
+ \glyphxscale#1\relax
+ \glyphyscale#1\relax
+ \setupinterlinespace
+ \samplefile{ward}%
+ \start
+ \bf
+ \samplefile{ward}%
+ \glyphxscale\numexpr(#1*2)/3\relax
+ \glyphyscale#1\relax
+ \samplefile{ward}%
+ \par
+ \stop
+ \def\TEST{y = \sqrt{x^2 + 1}^3}%
+ \dontleavehmode
+ \ruledhbox{\glyphxscale #1 \glyphyscale #1 $\left{\TEST\right}$}
+ \ruledhbox{\glyphxscale #1 \glyphyscale \numexpr#1*3\relax $\left{\TEST\right}$}
+ \ruledhbox{\glyphxscale \numexpr#1/2\relax \glyphyscale \numexpr#1*2\relax $\left{\TEST\right}$}
+ \par
+ \stop
+ \page
+}
+\stopbuffer
+
+\getbuffer
+
+% As often there is a musical timestamp to this text: discovering Julia Hofer
+% (bass, came there via checking out (of course) Leland Sklar, and now i have to
+% watch a bunch of Victor Wooten videos too) and Neon Vine's (play and combine
+% anything) on YT. Both examples of where (imo extensive) practicing real
+% instruments can bring you with todays diverse equipment. These are interesting
+% times (it's now last days of 2020).
+%
+% The initial \definescaledfont was replaced by \definetweakedfont in the first
+% week of Januari 2021, when I watched the joyful covers of Peter Gabriels
+% "Steam" by Yoyoka which shows that the future belongs to the real young kids
+% (so much explosive creativity!) and not to the old folks.
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-style.tex b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-style.tex
index 68b52043c25..51519f1374f 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-style.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-style.tex
@@ -3,6 +3,8 @@
\startenvironment followingup-style
+\enableexperiments[fonts.compact] % needed for font chapter
+
\usemodule[abbreviations-smallcaps]
\logo [LUAMETATEX] {LuaMeta\TeXsuffix}
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup.tex b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup.tex
index a9aaaf71c55..7d7d17851c2 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup.tex
@@ -28,6 +28,7 @@
\component followingup-mp
\component followingup-tex
\component followingup-retrospect
+ \component followingup-fonts
\stopbodymatter
\stopdocument
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/libraries/ecmascript-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/libraries/ecmascript-mkiv.tex
index 70350142c03..7a8bcd535a8 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/libraries/ecmascript-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/libraries/ecmascript-mkiv.tex
@@ -410,9 +410,9 @@ for:
\startsection[title=Colofon]
\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC author \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC website \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\stoptabulate
\stopsection
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex
index f1801efc0a0..07caca83c06 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex
@@ -240,17 +240,18 @@ There are some optional libraries present, like:
\starttabulate[|l|l|l|l|l|]
\FL
-\BC module \BC library \BC windows \BC unix \NC \NR
+\BC module \BC library \BC windows \BC unix \NC \NR
\ML
-\NC libs-imp-curl \NC curl \NC libcurl \NC libcurl \NC \NR
-\NC libs-imp-mysql \NC mysql \NC libmysql \NC libmysqlclient \NC \NR
-\NC libs-imp-sqlite \NC sqlite \NC sqlite3 \NC sqlite3 \NC \NR
-%NC libs-imp-postgress \NC libpg \NC libpg \NC libpg \NC \NR % untested
-\NC libs-imp-zint \NC libzint \NC libzint \NC libzint \NC \NR
-\NC libs-imp-mujs \NC libmujs \NC libmujs \NC libmujs \NC \NR
-\NC libs-imp-ghostscript \NC ghostscript \NC gswin64 \NC libgs \NC \NR
-\NC libs-imp-graphicsmagick \NC graphicsmagick \NC several \NC unknown \NC \NR
-%NC font-phb-imp-internal \NC hb \NC libharfbuzz \NC libharfbuzz \NC \NR % maybe, for idris, testing uniscribe
+\NC libs-imp-curl \NC curl \NC libcurl \NC libcurl \NC \NR
+\NC libs-imp-mysql \NC mysql \NC libmysql \NC libmysqlclient \NC \NR
+\NC libs-imp-sqlite \NC sqlite \NC sqlite3 \NC sqlite3 \NC \NR
+%NC libs-imp-postgress \NC libpg \NC libpg \NC libpg \NC \NR % untested
+\NC libs-imp-zint \NC libzint \NC libzint \NC libzint \NC \NR
+\NC libs-imp-mujs \NC libmujs \NC libmujs \NC libmujs \NC \NR
+\NC libs-imp-kpse \NC kpse \NC kpathsea*w64 \NC libkpathsea \NC \NR % left-over for mkii runner
+\NC libs-imp-ghostscript \NC ghostscript \NC gswin64 \NC libgs \NC \NR
+\NC libs-imp-graphicsmagick \NC graphicsmagick \NC several \NC unknown \NC \NR
+%NC font-phb-imp-internal \NC hb \NC libharfbuzz \NC libharfbuzz \NC \NR % maybe, for idris, testing uniscribe
\LL
\stoptabulate
@@ -276,9 +277,9 @@ at some point provide the libraries that we support.
\startsection[title=Colofon]
\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC author \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC website \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\NC comment \NC many thanks to Luigi Scarso for taking care of \FFI\ support in the engines \NC \NR
\stoptabulate
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex
index 986d07b1b61..9a097b8780c 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex
@@ -9,9 +9,7 @@
[title=boxes,
color=middlered]
-\startsection[title=Preamble]
-
-\startsubsection[title=Introduction]
+\startsection[title=Introduction]
An average \CONTEXT\ user will not use the low level box primitives but a basic
understanding of how \TEX\ works doesn't hurt. In fact, occasionally using a box
@@ -25,9 +23,9 @@ about all kind of glues, kerns and penalties, just boxes it is.
This explanation will be extended when I feel the need (or users have questions
that can be answered here).
-\stopsubsection
+\stopsection
-\startsubsection[title=Boxes]
+\startsection[title=Boxes]
This paragraph of text is made from lines that contain words that themselves
contain symbolic representations of characters. Each line is wrapped in a so
@@ -68,7 +66,7 @@ other hand wraps a linked list of so called nodes: glyphs, kerns, glue,
penalties, rules, boxes, etc. It is a container with properties like width,
height, depth and shift.
-\stopsubsection
+\stopsection
\stopsection
@@ -469,10 +467,10 @@ a private attribute we define one.
\startbuffer
\newattribute\MyAt
\setbox\scratchbox\hbox attr \MyAt 123 {whatever}
-[\the\boxattr\scratchbox\MyAt]
-\boxattr\scratchbox\MyAt 456
-[\the\boxattr\scratchbox\MyAt]
-[\ifnum\boxattr\scratchbox\MyAt>400 okay\fi]
+[\the\boxattribute\scratchbox\MyAt]
+\boxattribute\scratchbox\MyAt 456
+[\the\boxattribute\scratchbox\MyAt]
+[\ifnum\boxattribute\scratchbox\MyAt>400 okay\fi]
\stopbuffer
\typebuffer[option=TEX]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-characters.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-characters.tex
new file mode 100644
index 00000000000..ee3ab404442
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-characters.tex
@@ -0,0 +1,256 @@
+% language=us
+
+\environment lowlevel-style
+
+\startdocument
+ [title=characters,
+ color=middlered]
+
+\startsection[title=Introduction]
+
+This explanation is part of the low level manuals because in practice users will
+not have to deal with these matters in \MKIV\ and even less in \LMTX. You can
+skip to the last section for commands.
+
+\stopsection
+
+\startsection[title=History]
+
+If we travel back in time to when \TEX\ was written we end up in eight bit
+character universe. In fact, the first versions assumed seven bits, but for
+comfortable use with languages other than English that was not sufficient.
+Support for eight bits permits the usage of so called code pages as supported by
+operating systems. Although \ASCII\ input became kind of the standard soon
+afterwards, the engine can be set up for different encodings. This is not only
+true for \TEX, but for many of its companions, like \METAFONT\ and therefore
+\METAPOST. \footnote {This remapping to an internal representation (e.g. ebcdic)
+is not present in \LUATEX\ where we assume \UTF8 to be the input encoding. The
+\METAPOST\ library that comes with \LUATEX\ still has that code but in
+\LUAMETATEX\ it's gone. There one can set up the machinery to be \UTF8 aware
+too.}
+
+Core components of a \TEX\ engine are hyphenation of words, applying
+inter|-|character kerns and build ligatures. In traditional \TEX\ engines those
+processes are interwoven into the par builder but in \LUATEX\ these are separate
+stages. The original approach is the reason that there is a relation between the
+input encoding and the font encoding: the character in the input is the slot used
+in a reference to a glyph. When producing the final result (e.g.\ \PDF) there can
+also be a mapping to an index in a font resource.
+
+\starttyping
+input A [tex ->] font slot A [backend ->] glyph index A
+\stoptyping
+
+The mapping that \TEX\ does is normally one|-|to|-|one but an input character can
+undergo some transformation. For instance a character beyond \ASCII\ 126 can be
+made active and expand to some character number that then becomes the font slot.
+So, it is the expansion (or meaning) of a character that end up as numeric
+reference in the glyph node. Virtual fonts can introduce yet another remapping
+but that's only visible in the backend.
+
+Actually, in \LUATEX\ the same happens but in practice there is no need to go
+active because (at least in \CONTEXT) we assume a \UNICODE\ path so there the
+font slot is the \UNICODE\ got from the \UTF8 input.
+
+In the eight bit universe macro packages (have to) provide all kind of means to
+deal with (in the perspective of English) special characters. For instance, \type
+{\"a} would put a diaeresis on top of the a or even better, refer to a character
+in the encoding that the chosen font provides. Because there are some limitations
+of what can go in an eight bit font, and because in different countries the used
+\TEX\ fonts evolved kind of independent, we ended up with quite some different
+variants of fonts. It was only with the Latin Modern project that this became
+better. Interesting is that when we consider the fact that such a font has often
+also hardly used symbols (like registered or copyright) coming up with an
+encoding vector that covers most (latin based) European languages (scripts) is
+not impossible \footnote {And indeed in the Latin Modern project we came up with
+one but it was already to late for it to become popular.} Special symbols could
+simply go into a dedicated font, also because these are always accessed via a
+macro so who cares about the input. It never happened.
+
+Keep in mind that when \UTF8 is used with eight bit engines, \CONTEXT\ will
+convert sequences of characters into a slot in a font (depending on the font
+encoding used which itself depends on the coverage needed). For this every first
+(possible) byte of a multibyte \UTF\ sequence is an active character, which is no
+big deal because these are outside the \ASCII\ range. Normal \ASCII\ characters
+are single byte \UTF\ sequences and fall through without treatment.
+
+Anyway, in \CONTEXT\ \MKII\ we dealt with this by supporting mixed encodings,
+depending on the (local) language, referencing the relevant font. It permits
+users to enter the text in their preferred input encoding and also get the words
+properly hyphenated. But we can leave these \MKII\ details behind.
+
+\stopsection
+
+\startsection[title=The heritage]
+
+In \MKIV\ we got rid of input and font encodings, although one can still load
+files in a specific code page. \footnote {I'm not sure if users ever depend on an
+input encoding different from \UTF8.} We also kept the means to enter special
+characters, if only because text editors seldom support(ed) a wide range of
+visual editing of those. This is why we still have
+
+\starttyping[option=TEX]
+\"u \^a \v{s} \AE \ij \eacute \oslash
+\stoptyping
+
+and many more. The ones with one character names are rather common in the \TEX\
+community but it is definitely a weird mix of symbols. The next two are kind of
+outdated: in these days you delegate that to the font handler, where turning them
+into \quote {single} character references depends on what the font offers, how it
+is set up with respect to (for instance) ligatures, and even might depend on
+language or script.
+
+The ones with the long names partly are tradition, but as we have a lot of them,
+in \MKII\ they actually serve a purpose. These verbose names are used in the so
+called encoding vectors and are part of the \UTF\ expansion vectors. They are
+also used in labels so that we have a good indication if what goes in there:
+remember that in those times editors often didn't show characters, unless the
+font for display had them, or the operating system somehow provided them from
+another font. These verbose names are used for latin, greek and cyrillic and for
+some other scripts and symbols. They take up quite a bit of hash space and the
+format file. \footnote {In \MKII\ we have an abstract front|-|end with respect to
+encodings and also an abstract backend with respect to supported drivers but both
+approaches no longer make sense today.}
+
+\stopsection
+
+\startsection[title=The \LMTX\ approach]
+
+In the process of tagging all (public) macros in \LMTX\ (which happened in
+2020|-|2021) I wondered if we should keep these one character macros, the
+references to special characters and the verbose ones. When asked on the mailing
+list it became clear that users still expect the short ones to be present, often
+just because old \BIBTEX\ files are used that might need them. However, in \MKIV\
+and \LMTX\ we load \BIBTEX\ files in a way that turn these special character
+references into proper \UTF8 input so it makes a weak argument. Anyway, although
+they could go, for now we keep them because users expect them. However, in \LMTX\
+the implementation is somewhat different now, a bit more efficient in terms of
+hash and memory, potentially a bit less efficient in runtime, but no one will
+notice that.
+
+A new command has been introduced, the very short \type {\chr}.
+
+\startbuffer
+\chr {à} \chr {á} \chr {ä}
+\chr {`a} \chr {'a} \chr {"a}
+\chr {a acute} \chr {a grave} \chr {a umlaut}
+\chr {aacute} \chr {agrave} \chr {aumlaut}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+In the first line the composed character using two characters, a base and a so
+called mark. Actually, one doesn't have to use \type {\chr} in that case because
+\CONTEXT\ does already collapse characters for you. The second line looks like
+the shortcuts \type {\`}, \type {\'} and \type {\"}. The third and fourth lines
+could eventually replace the more symbolic long names, if we feel the need. Watch
+out: in \UNICODE\ input the marks come {\em after}.
+
+\startlines \getbuffer \stoplines
+
+Currently the repertoire is somewhat limited but it can be easily be extended. It
+all depends on user needs (doing Greek and Cyrillic for instance). The reason why
+we actually save code deep down is that the helpers for this have always been
+there. \footnote {So if needed I can port this approach back to \MKIV, but for
+now we keep it as is because we then have a reference.}
+
+The \type {\"} commands are now just aliases to more verbose and less hackery
+looking macros:
+
+\starttabulate[|||||]
+ \NC \type {\withgrave} \NC \withgrave {a} \NC \type {\`} \NC \`{a} \NC \NR
+ \NC \type {\withacute} \NC \withacute {a} \NC \type {\'} \NC \'{a} \NC \NR
+ \NC \type {\withcircumflex} \NC \withcircumflex {a} \NC \type {\^} \NC \^{a} \NC \NR
+ \NC \type {\withtilde} \NC \withtilde {a} \NC \type {\~} \NC \~{a} \NC \NR
+ \NC \type {\withmacron} \NC \withmacron {a} \NC \type {\=} \NC \={a} \NC \NR
+ \NC \type {\withbreve} \NC \withbreve {e} \NC \type {\u} \NC \u{e} \NC \NR
+ \NC \type {\withdotaccent} \NC \withdot {c} \NC \type {\.} \NC \.{c} \NC \NR
+ \NC \type {\withdiaeresis} \NC \withdieresis {e} \NC \type {\"} \NC \"{e} \NC \NR
+ \NC \type {\withring} \NC \withring {u} \NC \type {\r} \NC \r{u} \NC \NR
+ \NC \type {\withhungarumlaut} \NC \withhungarumlaut{u} \NC \type {\H} \NC \H{u} \NC \NR
+ \NC \type {\withcaron} \NC \withcaron {e} \NC \type {\v} \NC \v{e} \NC \NR
+ \NC \type {\withcedilla} \NC \withcedilla {e} \NC \type {\c} \NC \c{e} \NC \NR
+ \NC \type {\withogonek} \NC \withogonek {e} \NC \type {\k} \NC \k{e} \NC \NR
+\stoptabulate
+
+Not all fonts have these special characters. Most natural is to have them
+available as precomposed single glyphs, but it can be that they are just two
+shapes with the marks anchored to the base. It can even be that the font somehow
+overlays them, assuming (roughly) equal widths. The \type {compose} font feature
+in \CONTEXT\ normally can handle most well.
+
+An occasional ugly rendering doesn't matter that much: better have something than
+nothing. But when it's the main language (script) that needs them you'd better
+look for a font that handles them. When in doubt, in \CONTEXT\ you can enable
+checking:
+
+\starttabulate[|l|l|]
+ \BC command \BC equivalent to \NC \NR
+ \NC \type {\checkmissingcharacters} \NC \type{\enabletrackers[fonts.missing]} \NC \NR
+ \NC \type {\removemissingcharacters} \NC \type{\enabletrackers[fonts.missing=remove]} \NC \NR
+ \NC \type {\replacemissingcharacters} \NC \type{\enabletrackers[fonts.missing=replace]} \NC \NR
+ \NC \type {\handlemissingcharacters} \NC \type{\enabletrackers[fonts.missing={decompose,replace}]} \NC \NR
+\stoptabulate
+
+The decompose variant will try to turn a composed character into its components
+so that at least you get something. If that fails it will inject a replacement
+symbol that stands out so that you can check it. The console also mentions
+missing glyphs. You don't need to enable this by default \footnote {There is some
+overhead involved here.} but you might occasionally do it when you use a font for
+the first time.
+
+In \LMTX\ this mechanism has been upgraded so that replacements follow the shape
+and are actually real characters. The decomposition has not yet been ported back
+to \MKIV.
+
+The full list of commands can be queried when a tracing module is loaded:
+
+\startbuffer
+\usemodule[s][characters-combinations]
+
+\showcharactercombinations
+\stopbuffer
+
+\typebuffer
+
+We get this list:
+
+\getbuffer
+
+Some combinations are special for \CONTEXT\ because \UNICODE\ doesn't specify
+decomposition for all composed characters.
+
+\stopsection
+
+\startsubject[title=Colofon]
+
+\starttabulate
+\NC Author \NC Hans Hagen \NC \NR
+\NC \CONTEXT \NC \contextversion \NC \NR
+\NC \LUAMETATEX \NC \texengineversion \NC \NR
+\NC Support \NC www.pragma-ade.com \NC \NR
+\NC \NC contextgarden.net \NC \NR
+\stoptabulate
+
+\stopsubject
+
+\stopdocument
+
+% on an old machine, so consider them just relative measures
+%
+% mkiv lmtx
+%
+% 0.012 0.009 % faster core code
+% 0.028 0.036 % different io code path
+% 0.055 0.043 % different io code path / faster core code
+% 0.156 0.129 % more efficient resolving
+% 0.153 0.119 % more efficient resolving
+%
+% \ifdefined\withdieresis\else\let\withdieresis\"\fi % for mkiv
+%
+% \setbox0\hpack{\testfeatureonce{100000}{ü}} \par \elapsedtime \par % direct
+% \setbox0\hpack{\testfeatureonce{100000}{ü}} \par \elapsedtime \par % composed (input)
+% \setbox0\hpack{\testfeatureonce{100000}{u{}̈}} \par \elapsedtime \par % overlay
+% \setbox0\hpack{\testfeatureonce{100000}{\withdieresis{u}}} \par \elapsedtime \par % official also \"u
+% \setbox0\hpack{\testfeatureonce{100000}{\" u}} \par \elapsedtime \par % alias of previous
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-conditionals.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-conditionals.tex
index ea3c9e1a244..9be2fb4ec6f 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-conditionals.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-conditionals.tex
@@ -6,6 +6,8 @@
[title=conditionals,
color=middleblue]
+\pushoverloadmode
+
\startsection[title=Preamble]
\startsubsection[title=Introduction]
@@ -1121,13 +1123,15 @@ This test is like \type {\ifcmpnum} but for dimensions.
\startsubsection[title={\tex{ifchkdim}}]
-This test is like \type {\ifchknum} but for dimensions.
+This test is like \type {\ifchknum} but for dimensions. The last checked value is
+available as \type {\lastchknum}.
\stopsubsection
\startsubsection[title={\tex{ifdimval}}]
-This test is like \type {\ifnumval} but for dimensions.
+This test is like \type {\ifnumval} but for dimensions. The last checked value is
+available as \type {\lastchkdim}
\stopsubsection
@@ -1224,6 +1228,15 @@ defined at the user level or is a build in one. This one might evolve.
\stopsubsection
+\startsubsection[title={\tex{ifarguments}}]
+
+This conditional can be used to check how many arguments were matched. It only
+makes sense when used with macros defined with the \type {\tolerant} prefix
+and|/|or when the sentinel \type {\ignorearguments} after the arguments is used.
+More details can be found in the lowlevel macros manual.
+
+\stopsubsection
+
\startsubsection[title={\tex{orelse}}]
This it not really a test primitive but it does act that way. Say that we have this:
@@ -1254,13 +1267,16 @@ A bit nicer looks this:
\fi
\stoptyping
-We stay at the same level and the only test that cannot be used this way is \type
-{\ifcondition} but that is no real problem. Sometimes a more flat test tree had
-advantages but if you think that it gives better performance then you will be
-disappointed. The fact that we stay at the same level is compensated by a bit
-more parsing, so unless you have millions such cases (or expansions) it might
-make a bit of a difference. As mentioned, I'm a bit sensitive for how code looks so
-that was the main motivation for introducing it.
+% We stay at the same level and the only test that cannot be used this way is \type
+% {\ifcondition} but that is no real problem. Sometimes a more flat test tree had
+
+We stay at the same level. Sometimes a more flat test tree had advantages but if
+you think that it gives better performance then you will be disappointed. The
+fact that we stay at the same level is compensated by a bit more parsing, so
+unless you have millions such cases (or expansions) it might make a bit of a
+difference. As mentioned, I'm a bit sensitive for how code looks so that was the
+main motivation for introducing it. There is a companion \type {\orunless}
+continuation primitive.
A rather neat trick is the definition of \type {\quitcondition}:
@@ -1294,18 +1310,23 @@ reason to go this complex but obscure \TEX\ code attracts some users so \unknown
When you have a macro that has for instance assignments, and when you expand that
macro inside an \type {\edef}, these assignments are not actually expanded but
-tokenized. In \LUATEX\ there is a way to immediately apply these assignments and
-that feature can be used to write a fully expandable user test. For instance:
+tokenized. In \LUAMETATEX\ there is a way to apply these assignments without side
+effects and that feature can be used to write a fully expandable user test. For
+instance:
\startbuffer
\def\truecondition {\iftrue}
\def\falsecondition{\iffalse}
\def\fontwithidhaschar#1#2%
- {\immediateassignment\scratchcounter\numexpr\fontid\font\relax
- \immediateassignment\setfontid\numexpr#1\relax
+ {\beginlocalcontrol
+ \scratchcounter\numexpr\fontid\font\relax
+ \setfontid\numexpr#1\relax
+ \endlocalcontrol
\iffontchar\font\numexpr#2\relax
- \immediateassignment\setfontid\scratchcounter
+ \beginlocalcontrol
+ \setfontid\scratchcounter
+ \endlocalcontrol
\expandafter\truecondition
\else
\expandafter\falsecondition
@@ -1394,6 +1415,125 @@ with \type {\ifcondition} (it has bitten me already a few times).
\stopsection
+\startsection[title=Relaxing]
+
+When \TEX\ scans for a number or dimension it has to check tokens one by one. On
+the case of a number, the scanning stops when there is no digit, in the case of a
+dimension the unit determine the end of scanning. In the case of a number, when a
+token is not a digit that token gets pushed back. When digits are scanned a
+trailing space or \type {\relax} is pushed back. Instead of a number of dimension
+made from digits, periods and units, the scanner also accepts registers, both the
+direct accessors like \type {\count} and \type {\dimen} and those represented by
+one token. Take these definitions:
+
+\startbuffer
+\newdimen\MyDimenA \MyDimenA=1pt \dimen0=\MyDimenA
+\newdimen\MyDimenB \MyDimenB=2pt \dimen2=\MyDimenB
+\stopbuffer
+
+\typebuffer \getbuffer
+
+I will use these to illustrate the side effects of scanning. Watch the spaces
+in the result.
+
+% \startbuffer[a]
+% \testfeatureonce{1000000}{
+% \whatever{1pt}{2pt}%
+% \whatever{1pt}{1pt}%
+% \whatever{\dimen0}{\dimen2}%
+% \whatever{\dimen0}{\dimen0}%
+% \whatever\MyDimenA\MyDimenB
+% \whatever\MyDimenA\MyDimenB
+% } \elapsedtime
+% \stopbuffer
+
+\startbuffer[b]
+\starttabulate[|T|T|]
+\NC \type {\whatever{1pt}{2pt}} \NC \edef\temp{\whatever {1pt}{2pt}}[\meaning\temp] \NC \NR
+\NC \type {\whatever{1pt}{1pt}} \NC \edef\temp{\whatever {1pt}{1pt}}[\meaning\temp] \NC \NR
+\NC \type {\whatever{\dimen0}{\dimen2}} \NC \edef\temp{\whatever{\dimen0}{\dimen2}}[\meaning\temp] \NC \NR
+\NC \type {\whatever{\dimen0}{\dimen0}} \NC \edef\temp{\whatever{\dimen0}{\dimen0}}[\meaning\temp] \NC \NR
+\NC \type {\whatever\MyDimenA\MyDimenB} \NC \edef\temp{\whatever\MyDimenA\MyDimenB}[\meaning\temp] \NC \NR
+\NC \type {\whatever\MyDimenA\MyDimenB} \NC \edef\temp{\whatever\MyDimenA\MyDimenB}[\meaning\temp] \NC \NR
+\stoptabulate
+\stopbuffer
+
+First I show what effect we want to avoid. When second argument contains a number
+(digits) the zero will become part of it so we actually check \type {\dimen00}
+here.
+
+\startbuffer[c]
+\def\whatever#1#2%
+ {\ifdim#1=#20\else1\fi}
+\stopbuffer
+
+\typebuffer[c] \getbuffer[c,b]
+
+The solution is to add a space but watch how that one can end up in the result:
+
+\startbuffer[c]
+\def\whatever#1#2%
+ {\ifdim#1=#2 0\else1\fi}
+\stopbuffer
+
+\typebuffer[c] \getbuffer[c,b]
+
+A variant is using \type {\relax} and this time we get this token retained in
+the output.
+
+\startbuffer[c]
+\def\whatever#1#2%
+ {\ifdim#1=#2\relax0\else1\fi}
+\stopbuffer
+
+\typebuffer[c] \getbuffer[c,b]
+
+A solution that doesn't have side effects of forcing the end of a number (using a
+space or \type {\relax} is one where we use expressions. The added overhead of
+scanning expressions is taken for granted because the effect is what we like:
+
+\startbuffer[c]
+\def\whatever#1#2%
+ {\ifdim\dimexpr#1\relax=\dimexpr#2\relax0\else1\fi}
+\stopbuffer
+
+\typebuffer[c] \getbuffer[c,b]
+
+Just for completeness we show a more obscure trick: this one hides assignments to
+temporary variables. Although performance is okay, it is the least efficient
+one so far.
+
+\ifdefined\beginlocalcontrol
+
+\startbuffer[c]
+\def\whatever#1#2%
+ {\beginlocalcontrol
+ \MyDimenA#1\relax
+ \MyDimenB#2\relax
+ \endlocalcontrol
+ \ifdim\MyDimenA=\MyDimenB0\else1\fi}
+\stopbuffer
+
+\typebuffer[c] \getbuffer[c,b]
+
+\fi
+
+It is kind of a game to come up with alternatives but for sure those involve
+dirty tricks and more tokens (and runtime). The next can be considered a dirty
+trick too: we use a special variant of \type {\relax}. When a number is scanned
+it acts as relax, but otherwise it just is ignored and disappears.
+
+\ifdefined\norelax\else\let\norelax\relax\fi
+
+\startbuffer[c]
+\def\whatever#1#2%
+ {\ifdim#1=#2\norelax0\else1\fi}
+\stopbuffer
+
+\typebuffer[c] \getbuffer[c,b]
+
+\stopsection
+
\startsubject[title=Colofon]
\starttabulate
@@ -1406,4 +1546,18 @@ with \type {\ifcondition} (it has bitten me already a few times).
\stopsubject
+\popoverloadmode
+
\stopdocument
+
+% \def\foo{foo=bar}
+% \def\oof{foo!bar}
+% \scratchtoks{=}
+
+% \ifhasxtoks\scratchtoks{foo!bar} YES\else NOP\fi\par
+% \ifhasxtoks\scratchtoks{foo=bar} YES\else NOP\fi\par
+
+% \showluatokens\foo
+
+% \ifhastoks\scratchtoks\oof YES\else NOP\fi\par
+% \ifhastoks\scratchtoks\foo YES\else NOP\fi\par
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-expansion.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-expansion.tex
index 1e2e00a35ad..15faa802dc4 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-expansion.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-expansion.tex
@@ -315,7 +315,7 @@ Although you can never really get back to the original input, you can come prett
close, with:
\startbuffer
-\normaldetokenize{this can $ be anything \bgroup}
+\detokenize{this can $ be anything \bgroup}
\stopbuffer
\typebuffer[option=TEX]
@@ -432,9 +432,45 @@ These two macros now have the meaning:
\startsection[title={\LUAMETATEX\ primitives}]
-{\em todo}
+To be discussed:
+
+\starttyping
+\expand
+\expandtoken
+\localcontrol
+\localcontrolled
+\beginlocalcontrol ... \endlocalcontrol
+\immediate
+\stoptyping
+
+And maybe also here:
+
+\starttyping
+\tokenized : a bonus
+\scantokens : original etex, now using the lua method
+\stoptyping
% \aftergroups
+% \aftergrouped
+
+And:
+
+\starttyping
+ \def\foo{foo}
+\protected\def\oof{oof}
+
+\csname foo\endcsname
+\csname oof\endcsname
+\csname \foo\endcsname
+% \csname \oof\endcsname % error in luametatex
+
+\ifcsname foo\endcsname yes\else nop\fi
+\ifcsname oof\endcsname yes\else nop\fi
+\ifcsname \foo\endcsname yes\else nop\fi
+\ifcsname \oof\endcsname yes\else nop\fi % nop in luametatex
+\stoptyping
+
+\stoptext
\stopsection
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-grouping.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-grouping.tex
new file mode 100644
index 00000000000..eadcca6a9fd
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-grouping.tex
@@ -0,0 +1,170 @@
+% language=us
+
+\environment lowlevel-style
+
+\startdocument
+ [title=grouping,
+ color=middlecyan]
+
+\startsection[title=Introduction]
+
+This is a rather short explanation. I decided to write it after presenting the
+other topics at the 2019 \CONTEXT\ meeting where there was a question about
+grouping.
+
+\stopsection
+
+\startsection[title=\PASCAL]
+
+In a language like \PASCAL, the language that \TEX\ has been written in, or
+\MODULA, its successor, there is no concept of grouping like in \TEX. But we can
+find keywords that suggests this:
+
+\starttyping
+for i := 1 to 10 do begin ... end
+\stoptyping
+
+This language probably inspired some of the syntax of \TEX\ and \METAPOST. For
+instance an assignment in \METAPOST\ uses \type {:=} too. However, the \type
+{begin} and \type {end} don't really group but define a block of statements. You
+can have local variables in a procedure or function but the block is just a way
+to pack a sequence of statements.
+
+\stopsection
+
+\startsection[title=\TEX]
+
+In \TEX\ macros (or source code) the following can occur:
+
+\starttyping
+\begingroup
+ ...
+\endgroup
+\stoptyping
+
+as well as:
+
+\starttyping
+\bgroup
+ ...
+\egroup
+\stoptyping
+
+Here we really group in the sense that assignments to variables inside a group
+are forgotten afterwards. All assignments are local to the group unless they are
+explicitly done global:
+
+\starttyping
+\scratchcounter=1
+\def\foo{foo}
+\begingroup
+ \scratchcounter=2
+ \global\globalscratchcounter=2
+ \gdef\foo{FOO}
+\endgroup
+\stoptyping
+
+Here \type {\scratchcounter} is still one after the group is left but its global
+counterpart is now two. The \type {\foo} macro is also changed globally.
+
+Although you can use both sets of commands to group, you cannot mix them, so this
+will trigger an error:
+
+\starttyping
+\bgroup
+\endgroup
+\stoptyping
+
+The bottomline is: if you want a value to persist after the group, you need to
+explicitly change its value globally. This makes a lot of sense in the perspective
+of \TEX.
+
+\stopsection
+
+\startsection[title=\METAPOST]
+
+The \METAPOST\ language also has a concept of grouping but in this case it's more like a
+programming language.
+
+\starttyping
+begingroup ;
+ n := 123 ;
+engroup ;
+\stoptyping
+
+In this case the value of \type {n} is 123 after the group is left, unless you do
+this (for numerics there is actually no need to declare them):
+
+\starttyping
+begingroup ;
+ save n ; numeric n ; n := 123 ;
+engroup ;
+\stoptyping
+
+Given the use of \METAPOST\ (read: \METAFONT) this makes a lot of sense: often
+you use macros to simplify code and you do want variables to change. Grouping in
+this language serves other purposes, like hiding what is between these commands
+and let the last expression become the result. In a \type {vardef} grouping is
+implicit.
+
+So, in \METAPOST\ all assignments are global, unless a variable is explicitly
+saved inside a group.
+
+\stopsection
+
+\startsection[title=\LUA]
+
+In \LUA\ all assignments are global unless a variable is defines local:
+
+\starttyping
+local x = 1
+local y = 1
+for i = 1, 10 do
+ local x = 2
+ y = 2
+end
+\stoptyping
+
+Here the value of \type {x} after the loop is still one but \type {y} is now two.
+As in \LUATEX\ we mix \TEX, \METAPOST\ and \LUA\ you can mix up these concepts.
+Another mixup is using \type {:=}, \type {endfor}, \type {fi} in \LUA\ after done
+some \METAPOST\ coding or using \type {end} instead of \type {endfor} in
+\METAPOST\ which can make the library wait for more without triggering an error.
+Proper syntax highlighting in an editor clearly helps.
+
+\stopsection
+
+\startsection[title=\CCODE]
+
+The \LUA\ language is a mix between \PASCAL\ (which is one reason why I like it)
+and \CCODE.
+
+\starttyping
+int x = 1 ;
+int y = 1 ;
+for (i=1; i<=10;i++) {
+ int x = 2 ;
+ y = 2 ;
+}
+\stoptyping
+
+The semicolon is also used in \PASCAL\ but there it is a separator and not a
+statement end, while in \METAPOST\ it does end a statement (expression).
+
+\stopsection
+
+\stopsection
+
+\startsubject[title=Colofon]
+
+\starttabulate
+\NC Author \NC Hans Hagen \NC \NR
+\NC \CONTEXT \NC \contextversion \NC \NR
+\NC \LUAMETATEX \NC \texengineversion \NC \NR
+\NC Support \NC www.pragma-ade.com \NC \NR
+\NC \NC contextgarden.net \NC \NR
+\stoptabulate
+
+\stopsubject
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-macros.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-macros.tex
new file mode 100644
index 00000000000..ef527732be3
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-macros.tex
@@ -0,0 +1,904 @@
+% language=us
+
+% Extending the macro argument parser happened stepwise and at each step a bit of
+% \CONTEXT\ code was adapted for testing. At the beginning of October the 20201010
+% version of \LUAMETATEX\ was more of less complete, and I decided to adapt some
+% more and more intrusive too. Of course that resulted in some more files than I
+% had intended so mid October about 100 files were adapted. When this works out
+% well, I'll do some more. In the process many macros got the frozen property so
+% that was also a test and we'll see how that works out (as it can backfire). As
+% usual, here is a musical timestamp: working on this happened when Pineapple Thief
+% released \quotation {Versions of the Truth} which again a magnificent drumming by
+% Gavin Harrison.
+
+
+% \permanent\tolerant\protected\def\xx[#1]#*#;[#2]#:#3% loops .. todo
+
+
+\usemodule[system-tokens]
+
+\environment lowlevel-style
+
+\startdocument
+ [title=macros,
+ color=middleorange]
+
+\startsection[title=Preamble]
+
+This chapter overlaps with other chapters but brings together some extensions to
+the macro definition and expansion parts. As these mechanisms were stepwise
+extended, the other chapters describe intermediate steps in the development.
+
+Now, in spite of the extensions discussed here the main ides is still that we
+have \TEX\ act like before. We keep the charm of the macro language but these
+additions make for easier definitions, but (at least initially) none that could
+not be done before using more code.
+
+\stopsection
+
+\startsection[title=Definitions]
+
+A macro definition normally looks like like this: \footnote {The \type
+{\dontleavehmode} command make the examples stay on one line.}
+
+\startbuffer[definition]
+\def\macro#1#2%
+ {\dontleavehmode\hbox to 6em{\vl\type{#1}\vl\type{#2}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+Such a macro can be used as:
+
+\startbuffer[example]
+\macro {1}{2}
+\macro {1} {2} middle space gobbled
+\macro 1 {2} middle space gobbled
+\macro {1} 2 middle space gobbled
+\macro 1 2 middle space gobbled
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+We show the result with some comments about how spaces are handled:
+
+\startlines \getbuffer[example] \stoplines
+
+A definition with delimited parameters looks like this:
+
+\startbuffer[definition]
+\def\macro[#1]%
+ {\dontleavehmode\hbox to 6em{\vl\type{#1}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+When we use this we get:
+
+\startbuffer[example]
+\macro [1]
+\macro [ 1] leading space kept
+\macro [1 ] trailing space kept
+\macro [ 1 ] both spaces kept
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+Again, watch the handling of spaces:
+
+\startlines \getbuffer[example] \stoplines
+
+Just for the record we show a combination:
+
+\startbuffer[definition]
+\def\macro[#1]#2%
+ {\dontleavehmode\hbox to 6em{\vl\type{#1}\vl\type{#2}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+With this:
+
+\startbuffer[example]
+\macro [1]{2}
+\macro [1] {2}
+\macro [1] 2
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+we can again see the spaces go away:
+
+\startlines \getbuffer[example] \stoplines
+
+A definition with two separately delimited parameters is given next:
+
+\startbuffer[definition]
+\def\macro[#1#2]%
+ {\dontleavehmode\hbox to 6em{\vl\type{#1}\vl\type{#2}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+When used:
+
+\startbuffer[example]
+\macro [12]
+\macro [ 12] leading space gobbled
+\macro [12 ] trailing space kept
+\macro [ 12 ] leading space gobbled, trailing space kept
+\macro [1 2] middle space kept
+\macro [ 1 2 ] leading space gobbled, middle and trailing space kept
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+We get ourselves:
+
+\startlines \getbuffer[example] \stoplines
+
+These examples demonstrate that the engine does some magic with spaces before
+(and therefore also between multiple) parameters.
+
+We will now go a bit beyond what traditional \TEX\ engines do and enter the
+domain of \LUAMETATEX\ specific parameter specifiers. We start with one that
+deals with this hard coded space behavior:
+
+\startbuffer[definition]
+\def\macro[#^#^]%
+ {\dontleavehmode\hbox to 6em{\vl\type{#1}\vl\type{#2}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+The \type {#^} specifier will count the parameter, so here we expect again two
+arguments but the space is kept when parsing for them.
+
+\startbuffer[example]
+\macro [12]
+\macro [ 12]
+\macro [12 ]
+\macro [ 12 ]
+\macro [1 2]
+\macro [ 1 2 ]
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+Now keep in mind that we could deal well with all kind of parameter handling in
+\CONTEXT\ for decades, so this is not really something we missed, but it
+complements the to be discussed other ones and it makes sense to have that level
+of control. Also, availability triggers usage. Nevertheless, some day the \type
+{#^} specifier will come in handy.
+
+\startlines \getbuffer[example] \stoplines
+
+We now come back to an earlier example:
+
+\startbuffer[definition]
+\def\macro[#1]%
+ {\dontleavehmode\hbox spread 1em{\vl\type{#1}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+When we use this we see that the braces in the second call are removed:
+
+\startbuffer[example]
+\macro [1]
+\macro [{1}]
+\stopbuffer
+
+\typebuffer[example][option=TEX] \getbuffer[example]
+
+This can be prohibited by the \type {#+} specifier, as in:
+
+\startbuffer[definition]
+\def\macro[#+]%
+ {\dontleavehmode\hbox spread 1em{\vl\type{#1}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+As we see, the braces are kept:
+
+\startbuffer[example]
+\macro [1]
+\macro [{1}]
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+Again, we could easily get around that (for sure intended) side effect but it just makes nicer
+code when we have a feature like this.
+
+\getbuffer[example]
+
+Sometimes you want to grab an argument but are not interested in the results. For this we have
+two specifiers: one that just ignores the argument, and another one that keeps counting but
+discards it, i.e.\ the related parameter is empty.
+
+\startbuffer[definition]
+\def\macro[#1][#0][#3][#-][#4]%
+ {\dontleavehmode\hbox spread 1em
+ {\vl\type{#1}\vl\type{#2}\vl\type{#3}\vl\type{#4}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+The second argument is empty and the fourth argument is simply ignored which is why we need
+\type {#4} for the fifth entry.
+
+\startbuffer[example]
+\macro [1][2][3][4][5]
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+Here is proof that it works:
+
+\getbuffer[example]
+
+The reasoning behind dropping arguments is that for some cases we get around the
+nine argument limitation, but more important is that we don't construct token
+lists that are not used, which is more memory (and maybe even \CPU\ cache)
+friendly.
+
+Spaces are always kind of special in \TEX, so it will be no surprise that we have
+another specifier that relates to spaces.
+
+\startbuffer[definition]
+\def\macro[#1]#*[#2]%
+ {\dontleavehmode\hbox spread 1em{\vl\type{#1}\vl\type{#2}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+This permits usage like the following:
+
+\startbuffer[example]
+\macro [1][2]
+\macro [1] [2]
+\stopbuffer
+
+\typebuffer[example][option=TEX] \getbuffer[example]
+
+Without the optional \quote {grab spaces} specifier the second line would
+possibly throw an error. This because \TEX\ then tries to match \type{][} so the
+\type {] [} in the input is simply added to the first argument and the next
+occurrence of \type {][} will be used. That one can be someplace further in your
+source and if not \TEX\ complains about a premature end of file. But, with the
+\type {#*} option it works out okay (unless of course you don't have that second
+argument \type {[2]}.
+
+Now, you might wonder if there is a way to deal with that second delimited
+argument being optional and of course that can be programmed quite well in
+traditional macro code. In fact, \CONTEXT\ does that a lot because it is set up
+as a parameter driven system with optional arguments. That subsystem has been
+optimized to the max over years and it works quite well and performance wise
+there is very little to gain. However, as soon as you enable tracing you end up
+in an avalanche of expansions and that is no fun.
+
+This time the solution is not in some special specifier but in the way a macro
+gets defined.
+
+\startbuffer[definition]
+\tolerant\def\macro[#1]#*[#2]%
+ {\dontleavehmode\hbox spread 1em{\vl\type{#1}\vl\type{#2}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+The magic \type {\tolerant} prefix with delimited arguments and just quits when
+there is no match. So, this is acceptable:
+
+\startbuffer[example]
+\macro [1][2]
+\macro [1] [2]
+\macro [1]
+\macro
+\stopbuffer
+
+\typebuffer[example][option=TEX] \getbuffer[example]
+
+We can check how many arguments have been processed with a dedicated conditional:
+
+\startbuffer[definition]
+\tolerant\def\macro[#1]#*[#2]%
+ {\ifarguments 0\or 1\or 2\or ?\fi: \vl\type{#1}\vl\type{#2}\vl}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+We use this test:
+
+\startbuffer[example]
+\macro [1][2] \macro [1] [2] \macro [1] \macro
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+The result is: \inlinebuffer[example]\ which is what we expect because we flush
+inline and there is no change of mode. When the following definition is used in
+display mode, the leading \type {n=} can for instance start a new paragraph and
+when code in \type {\everypar} you can loose the right number when macros get
+expanded before the \type {n} gets injected.
+
+\starttyping[option=TEX]
+\tolerant\def\macro[#1]#*[#2]%
+ {n=\ifarguments 0\or 1\or 2\or ?\fi: \vl\type{#1}\vl\type{#2}\vl}
+\stoptyping
+
+In addition to the \type {\ifarguments} test primitive there is also a related
+internal counter \type {\lastarguments} set that you can consult, so the \type
+{\ifarguments} is actually just a shortcut for \typ {\ifcase \lastarguments}.
+
+We now continue with the argument specifiers and the next two relate to this optional
+grabbing. Consider the next definition:
+
+\startbuffer[definition]
+\tolerant\def\macro#1#*#2%
+ {\dontleavehmode\hbox spread 1em{\vl\type{#1}\vl\type{#2}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+With this test:
+
+\startbuffer[example]
+\macro {1} {2}
+\macro {1}
+\macro
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+We get:
+
+\getbuffer[example]
+
+This is okay because the last \type {\macro} is a valid (single token) argument. But, we
+can make the braces mandate:
+
+\startbuffer[definition]
+\tolerant\def\macro#=#*#=%
+ {\dontleavehmode\hbox spread 1em{\vl\type{#1}\vl\type{#2}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+Here the \type {#=} forces a check for braces, so:
+
+\startbuffer[example]
+\macro {1} {2}
+\macro {1}
+\macro
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+gives this:
+
+\getbuffer[example]
+
+However, we do loose these braces and sometimes you don't want that. Of course when you pass the
+results downstream to another macro you can always add them, but it was cheap to add a related
+specifier:
+
+\startbuffer[definition]
+\tolerant\def\macro#_#*#_%
+ {\dontleavehmode\hbox spread 1em{\vl\type{#1}\vl\type{#2}\vl\hss}}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+Again, the magic \type {\tolerant} prefix works will quit scanning when there is
+no match. So:
+
+\startbuffer[example]
+\macro {1} {2}
+\macro {1}
+\macro
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+leads to:
+
+\getbuffer[example]
+
+When you're tolerant it can be that you still want to pick up some argument
+later on. This is why we have a continuation option.
+
+\startbuffer[definition]
+\tolerant\def\foo [#1]#*[#2]#:#3{!#1!#2!#3!}
+\tolerant\def\oof[#1]#*[#2]#:(#3)#:#4{!#1!#2!#3!#4!}
+\tolerant\def\ofo [#1]#:(#2)#:#3{!#1!#2!#3!}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+Hopefully the next example demonstrates how it works:
+
+\startbuffer[example]
+\foo{3} \foo[1]{3} \foo[1][2]{3}
+\oof{4} \oof[1]{4} \oof[1][2]{4}
+\oof[1][2](3){4} \oof[1](3){4} \oof(3){4}
+\ofo{3} \ofo[1]{3}
+\ofo[1](2){3} \ofo(2){3}
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+As you can see we can have multiple continuations using the \type {#:} directive:
+
+\startlines \getbuffer[example] \stoplines
+
+The last specifier doesn't work well with the \type {\ifarguments} state because
+we no longer know what arguments were skipped. This is why we have another test
+for arguments. A zero value means that the next token is not a parameter
+reference, a value of one means that a parameter has been set and a value of two
+signals an empty parameter. So, it reports the state of the given parameter as
+a kind if \type {\ifcase}.
+
+\startbuffer[definition]
+\def\foo#1#2{ [\ifparameter#1\or(ONE)\fi\ifparameter#2\or(TWO)\fi] }
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+\startbuffer[example]
+\foo{1}{2} \foo{1}{} \foo{}{2} \foo{}{}
+\stopbuffer
+
+Of course the test has to be followed by a valid parameter specifier:
+
+\typebuffer[example][option=TEX]
+
+The previous code gives this:
+
+\getbuffer[example]
+
+A combination check \type {\ifparameters}, again a case, matches the first
+parameter that has a value set.
+
+We could add plenty of specifiers but we need to keep in ind that we're not
+talking of an expression scanner. We need to keep performance in mind, so nesting
+and backtracking are no option. We also have a limited set of useable single
+characters, but here's one that uses a symbol that we had left:
+
+\startbuffer[definition]
+\def\startfoo[#/]#/\stopfoo{ [#1](#2) }
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+\startbuffer[example]
+\startfoo [x ] x \stopfoo
+\startfoo [ x ] x \stopfoo
+\startfoo [ x] x \stopfoo
+\startfoo [ x] \par x \par \par \stopfoo
+\stopbuffer
+
+The slash directive removes leading and trailing so called spacers as well as tokens
+that represent a paragraph end:
+
+\typebuffer[example][option=TEX]
+
+So we get this:
+
+\getbuffer[example]
+
+The next directive, the quitter \type {#;}, is demonstrated with an example. When
+no match has occurred, scanning picks up after this signal, otherwise we just
+quit.
+
+\startbuffer[example]
+\tolerant\def\foo[#1]#;(#2){/#1/#2/}
+
+\foo[1]\quad\foo[2]\quad\foo[3]\par
+\foo(1)\quad\foo(2)\quad\foo(3)\par
+
+\tolerant\def\foo[#1]#;#={/#1/#2/}
+
+\foo[1]\quad\foo[2]\quad\foo[3]\par
+\foo{1}\quad\foo{2}\quad\foo{3}\par
+
+\tolerant\def\foo[#1]#;#2{/#1/#2/}
+
+\foo[1]\quad\foo[2]\quad\foo[3]\par
+\foo{1}\quad\foo{2}\quad\foo{3}\par
+
+\tolerant\def\foo[#1]#;(#2)#;#={/#1/#2/#3/}
+
+\foo[1]\quad\foo[2]\quad\foo[3]\par
+\foo(1)\quad\foo(2)\quad\foo(3)\par
+\foo{1}\quad\foo{2}\quad\foo{3}\par
+\stopbuffer
+
+\typebuffer[example][option=TEX] \startpacked \getbuffer[example] \stoppacked
+
+I have to admit that I don't really need it but it made some macros that I was
+redefining behave better, so there is some self|-|interest here. Anyway, I
+considered some other features, like picking up a detokenized argument but I
+don't expect that to be of much use. In the meantime we ran out of reasonable
+characters, but some day \type {#?} and \type {#!} might show up, or maybe I find
+a use for \type {#<} and \type {#>}. A summary of all this is given here:
+
+\starttabulate[|T|i2l|]
+\FL
+\NC + \NC keep the braces \NC \NR
+\NC - \NC discard and don't count the argument \NC \NR
+\NC / \NC remove leading an trailing spaces and pars \NC \NR
+\NC = \NC braces are mandate \NC \NR
+\NC _ \NC braces are mandate and kept \NC \NR
+\NC ^ \NC keep leading spaces \NC \NR
+\ML
+\NC 1-9 \NC an argument \NC \NR
+\NC 0 \NC discard but count the argument \NC \NR
+\ML
+\NC * \NC ignore spaces \NC \NR
+\NC : \NC pick up scanning here \NC \NR
+\NC ; \NC quit scanning \NC \NR
+\LL
+\stoptabulate
+
+\stopsection
+
+\startsection[title=Runaway arguments]
+
+There is a particular troublesome case left: a runaway argument. The solution is
+not pretty but it's the only way: we need to tell the parser that it can quit.
+
+\startbuffer[definition]
+\tolerant\def\foo[#1=#2]%
+ {\ifarguments 0\or 1\or 2\or 3\or 4\fi:\vl\type{#1}\vl\type{#2}\vl}
+\stopbuffer
+
+\typebuffer[definition][option=TEX] \getbuffer[definition]
+
+\startbuffer[example]
+\dontleavehmode \foo[a=1]
+\dontleavehmode \foo[b=]
+\dontleavehmode \foo[=]
+\dontleavehmode \foo[x]\ignorearguments
+\stopbuffer
+
+The outcome demonstrates that one still has to do some additional checking for sane
+results and there are alternative way to (ab)use this mechanism. It all boils down
+to a clever combination of delimiters and \type {\ignorearguments}.
+
+\typebuffer[example][option=TEX]
+
+All calls are accepted:
+
+\startlines \getbuffer[example] \stoplines
+
+Just in case you wonder about performance: don't expect miracles here. On the one
+hand there is some extra overhead in the engine (when defining macros as well as
+when collecting arguments during a macro call) and maybe using these new features
+can sort of compensate that. As mentioned: the gain is mostly in cleaner macro
+code and less clutter in tracing. And I just want the \CONTEXT\ code to look
+nice: that way users can look in the source to see what happens and not drown in
+all these show|-|off tricks, special characters like underscores, at signs,
+question marks and exclamation marks.
+
+For the record: I normally run tests to see if there are performance side effects
+and as long as processing the test suite that has thousands of files of all kind
+doesn't take more time it's okay. Actually, there is a little gain in \CONTEXT\
+but that is to be expected, but I bet users won't notice it, because it's easily
+offset by some inefficient styling. Of course another gain of loosing some
+indirectness is that error messages point to the macro that the user called for
+and not to some follow up.
+
+\stopsection
+
+\startsection[title=Introspection]
+
+A macro has a meaning. You can serialize that meaning as follows:
+
+\startbuffer[definition]
+\tolerant\protected\def\foo#1[#2]#*[#3]%
+ {(1=#1) (2=#3) (3=#3)}
+
+\meaning\foo
+\stopbuffer
+
+\typebuffer[definition][option=TEX]
+
+The meaning of \type {\foo} comes out as:
+
+\startnarrower \getbuffer[definition] \stopnarrower
+
+When you load the module \type {system-tokens} you can also say:
+
+\startbuffer[example]
+\luatokentable\foo
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+This produces a table of tokens specifications:
+
+{\getbuffer[definition]\getbuffer[example]}
+
+A token list is a linked list of tokens. The magic numbers in the first column
+are the token memory pointers. and because macros (and token lists) get recycled
+at some point the available tokens get scattered, which is reflected in the order
+of these numbers. Normally macros defined in the macro package are more sequential
+because they stay around from the start. The second and third row show the so
+called command code and the specifier. The command code groups primitives in
+categories, the specifier is an indicator of what specific action will follow, a
+register number a reference, etc. Users don't need to know these details. This
+macro is a special version of the online variant:
+
+\starttyping[option=TEX]
+\showluatokens\foo
+\stoptyping
+
+That one is always available and shows a similar list on the console. Again, users
+normally don't want to know such details.
+
+\startsection[title=nesting]
+
+You can nest macros, as in:
+
+\startbuffer
+\def\foo#1#2{\def\oof##1{<#1>##1<#2>}}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+At first sight the duplication of \type {#} looks strange but this is what
+happens. When \TEX\ scans the definition of \type {\foo} it sees two arguments.
+Their specification ends up in the preamble that defines the matching. When the
+body is scanned, the \type {#1} and \type {#2} are turned into a parameter
+reference. In order to make nested macros with arguments possible a \type {#}
+followed by another \type {#} becomes just one \type {#}. Keep in mind that the
+definition of \type {\oof} is delayed till the macro \type {\foo} gets expanded.
+That definition is just stored and the only thing that get's replaced are the two
+references to a macro parameter
+
+\luatokentable\foo
+
+Now, when we look at these details, it might become clear why for instance we
+have \quote {variable} names like \type {#4} and not \type {#whatever} (with or
+without hash). Macros are essentially token lists and token lists can be seen as
+a sequence of numbers. This is not that different from other programming
+environments. When you run into buzzwords like \quote {bytecode} and \quote
+{virtual machines} there is actually nothing special about it: some high level
+programming (using whatever concept, and in the case of \TEX\ it's macros)
+eventually ends up as a sequence of instructions, say bytecodes. Then you need
+some machinery to run over that and act upon those numbers. It's something you
+arrive at naturally when you play with interpreting languages. \footnote {I
+actually did when I wrote an interpreter for some computer assisted learning
+system, think of a kind of interpreted \PASCAL, but later realized that it was a a
+bytecode plus virtual machine thing. I'd just applied what I learned when playing
+with eight bit processors that took bytes, and interpreted opcodes and such.
+There's nothing spectacular about all this and I only realized decades later that
+the buzzwords describes old natural concepts.}
+
+So, internally a \type {#4} is just one token, a operator|-|operand combination
+where the operator is \quotation {grab a parameter} and the operand tells
+\quotation {where to store} it. Using names is of course an option but then one
+has to do more parsing and turn the name into a number \footnote {This is kind of
+what \METAPOST\ does with parameters to macros. The side effect is that in
+reporting you get \type {text0}, \type {expr2} and such reported which doesn't
+make things more clear.}, add additional checking in the macro body, figure out
+some way to retain the name for the purpose of reporting (which then uses more
+token memory or strings). It is simply not worth the trouble, let alone the fact
+that we loose performance, and when \TEX\ showed up those things really mattered.
+
+It is also important to realize that a \type {#} becomes either a preamble token
+(grab an argument) or a reference token (inject the passed tokens into a new
+input level). Therefore the duplication of hash tokens \type {##} that you see in
+macro nested bodies also makes sense: it makes it possible for the parser to
+distinguish between levels. Take:
+
+\starttyping[option=TEX]
+\def\foo#1{\def\oof##1{#1##1#1}}
+\stoptyping
+
+Of course one can think of this:
+
+\starttyping[option=TEX]
+\def\foo#fence{\def\oof#text{#fence#text#fence}}
+\stoptyping
+
+But such names really have to be unique then! Actually \CONTEXT\ does have an
+input method that supports such names, but discussing it here is a bit out of
+scope. Now, imagine that in the above case we use this:
+
+\starttyping[option=TEX]
+\def\foo[#1][#2]{\def\oof##1{#1##1#2}}
+\stoptyping
+
+If you're a bit familiar with the fact that \TEX\ has a model of category codes
+you can imagine that a predictable \quotation {hash followed by a number} is way
+more robust than enforcing the user to ensure that catcodes of \quote {names} are
+in the right category (read: is a bracket part of the name or not). So, say that
+we go completely arbitrary names, we then suddenly needs some escaping, like:
+
+\starttyping[option=TEX]
+\def\foo[#{left}][#{right}]{\def\oof#{text}{#{left}#{text}#{right}}}
+\stoptyping
+
+And, if you ever looked into macro packages, you will notice that they differ in
+the way they assign category codes. Asking users to take that into account when
+defining macros makes not that much sense.
+
+So, before one complains about \TEX\ being obscure (the hash thing), think twice.
+Your demand for simplicity for your coding demand will make coding more
+cumbersome for the complex cases that macro packages have to deal with. It's
+comparable using \TEX\ for input or using (say) mark down. For simple documents
+the later is fine, but when things become complex, you end up with similar
+complexity (or even worse because you lost the enforced detailed structure). So,
+just accept the unavoidable: any language has its peculiar properties (and for
+sure I do know why I dislike some languages for it). The \TEX\ system is not the
+only one where dollars, percent signs, ampersands and hashes have special
+meaning.
+
+\stopsection
+
+\startsection[title=Prefixes]
+
+Traditional \TEX\ has three prefixes that can be used with macros: \type {\global},
+\type {\outer} and \type {\long}. The last two are no|-|op's in \LUAMETATEX\ and
+if you want to know what they do (did) you can look it up in the \TEX book. The
+\ETEX\ extension gave us \type {\protected}.
+
+In \LUAMETATEX\ we have \type {\global}, \type {\protected}, \type {\tolerant}
+and overload related prefixes like \type {\frozen}. A protected macro is one that
+doesn't expand in an expandable context, so for instance inside an \type {\edef}.
+You can force expansion by using the \type {\expand} primitive in front which is
+also something \LUAMETATEX.
+
+% A protected macro can be made expandable by \typ {\unletprotected} and can be
+% protected with \typ {\letprotected}.
+%
+% \startbuffer[example]
+% \def\foo{foo} \edef\oof{oof\foo} 1: \meaning\oof
+% \protected\def\foo{foo} \edef\oof{oof\foo} 2: \meaning\oof
+% \unletprotected \foo \edef\oof{oof\foo} 3: \meaning\oof
+% \stopbuffer
+%
+% \typebuffer[example][option=TEX]
+%
+% \startlines \getbuffer[example] \stoplines
+
+Frozen macros cannot be redefined without some effort. This feature can to some
+extent be used to prevent a user from overloading, but it also makes it harder
+for the macro package itself to redefine on the fly. You can remove the lock with
+\typ {\unletfrozen} and add a lock with \typ {\letfrozen} so in the end users
+still have all the freedoms that \TEX\ normally provides.
+
+\startbuffer[example]
+ \def\foo{foo} 1: \meaning\foo
+ \frozen\def\foo{foo} 2: \meaning\foo
+ \unletfrozen \foo 3: \meaning\foo
+\protected\frozen\def\foo{foo} 4: \meaning\foo
+ \unletfrozen \foo 5: \meaning\foo
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+\startlines \overloadmode0 \getbuffer[example] \stoplines
+
+This actually only works when you have set \type {\overloadmode} to a value that
+permits redefining a frozen macro, so for the purpose of this example we set it
+to zero.
+
+A \type {\tolerant} macro is one that will quit scanning arguments when a
+delimiter cannot be matched. We saw examples of that in a previous section.
+
+These prefixes can be chained (in arbitrary order):
+
+\starttyping[option=TEX]
+\frozen\tolerant\protected\global\def\foo[#1]#*[#2]{...}
+\stoptyping
+
+There is actually an additional prefix, \type {\immediate} but that one is there
+as signal for a macro that is defined in and handled by \LUA. This prefix can
+then perform the same function as the one in traditional \TEX, where it is used
+for backend related tasks like \type {\write}.
+
+Now, the question is of course, to what extent will \CONTEXT\ use these new
+features. One important argument in favor of using \type {\tolerant} is that it
+gives (hopefully) better error messages. It also needs less code due to lack of
+indirectness. Using \type {\frozen} adds some safeguards although in some places
+where \CONTEXT\ itself overloads commands, we need to defrost. Adapting the code
+is a tedious process and it can introduce errors due to mistypings, although
+these can easily be fixed. So, it will be used but it will take a while to adapt
+the code base.
+
+One problem with frozen macros is that they don't play nice with for instance
+\type {\futurelet}. Also, there are places in \CONTEXT\ where we actually do
+redefine some core macro that we also want to protect from redefinition by a
+user. One can of course \type {\unletfrozen} such a command first but as a bonus
+we have a prefix \type {\overloaded} that can be used as prefix. So, one can easily
+redefine a frozen macro but it takes a little effort. After all, this feature is
+mainly meant to protect a user for side effects of definitions, and not as final
+blocker. \footnote {As usual adding features like this takes some experimenting
+and we're now at the third variant of the implementation, so we're getting there.
+The fact that we can apply such features in large macro package like \CONTEXT\
+helps figuring out the needs and best approaches.}
+
+A frozen macro can still be overloaded, so what if we want to prevent that? For
+this we have the \type {\permanent} prefix. Internally we also create primitives
+but we don't have a prefix for that. But we do have one for a very special case
+which we demonstrate with an example:
+
+\startbuffer[example]
+\def\FOO % trickery needed to pick up an optional argument
+ {\noalign{\vskip10pt}}
+
+\noaligned\protected\tolerant\def\OOF[#1]%
+ {\noalign{\vskip\iftok{#1}\emptytoks10pt\else#1\fi}}
+
+\starttabulate[|l|l|]
+ \NC test \NC test \NC \NR
+ \NC test \NC test \NC \NR
+ \FOO
+ \NC test \NC test \NC \NR
+ \OOF[30pt]
+ \NC test \NC test \NC \NR
+ \OOF
+ \NC test \NC test \NC \NR
+\stoptabulate
+\stopbuffer
+
+\typebuffer[example][option=TEX]
+
+When \TEX\ scans input (from a file or token list) and starts an alignment, it
+will pick up rows. When a row is finished it will look ahead for a \type
+{\noalign} and it expands the next token. However, when that token is protected,
+the scanner will not see a \type {\noalign} in that macro so it will likely start
+complaining when that next macro does get expanded and produces a \type
+{\noalign} when a cell is built. The \type {\noaligned} prefix flags a macro as
+being one that will do some \type {\noalign} as part of its expansion. This trick
+permits clean macros that pick up arguments. Of course it can be done with
+traditional means but this whole exercise is about making the code look nice.
+
+The table comes out as:
+
+\getbuffer[example]
+
+One can check the flags with \type {\ifflags} which takes a control sequence and
+a number, where valid numbers are:
+
+\starttabulate[|r|lw(8em)|r|lw(8em)|r|lw(8em)|r|lw(8em)|]
+\NC \the\frozenflagcode \NC frozen
+\NC \the\permanentflagcode \NC permanent
+\NC \the\immutableflagcode \NC immutable
+\NC \the\primitiveflagcode \NC primitive \NC \NR
+\NC \the\mutableflagcode \NC mutable
+\NC \the\noalignedflagcode \NC noaligned
+\NC \the\instanceflagcode \NC instance
+\NC \NC \NC \NR
+\stoptabulate
+
+The level of checking is controlled with the \type {\overloadmode} but I'm still
+not sure about how many levels we need there. A zero value disables checking,
+the values 1 and 3 give warnings and the values 2 and 4 trigger an error.
+
+\stopsection
+
+\stopdocument
+
+freezing pitfalls:
+
+- \futurelet : \overloaded needed
+- \let : \overloaded sometimes needed
+
+primitive protection:
+
+\newif\iffoo \footrue \foofalse : problem when we make iftrue and iffalse
+permanent ... they inherit, so we can't let them, we need a not permanent
+alias which is again tricky ... something native?
+
+immutable : still \count000 but we can consider blocking that, for instance
+by \def\count{some error}
+
+\defcsname
+\edefcsname
+\letcsname
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex
new file mode 100644
index 00000000000..3098333f013
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex
@@ -0,0 +1,948 @@
+% language=us
+
+\environment lowlevel-style
+
+\startdocument
+ [title=paragraphs,
+ color=middlecyan]
+
+\startsection[title=Introduction]
+
+This manual is mostly discussing a few low level wrappers around low level \TEX\
+features. Its writing is triggered by an update to the \METAFUN\ and \LUAMETAFUN\
+manuals where we mess a bit with shapes. It gave a good reason to also cover some
+more paragraph related topics but it might take a while to complete. Remind me if
+you feel that takes too much time.
+
+Because paragraphs and their construction are rather central to \TEX, you can
+imagine that the engine exposes dealing with them. This happens via commands
+(primitives) but only when it's robust. Then there are callbacks, and some
+provide detailed information about what we're dealing with. However, intercepting
+node lists can already be hairy and we do that a lot in \CONTEXT. Intercepting
+and tweaking paragraph properties is even more tricky, which is why we try to
+avoid that in the core. But \unknown\ in the following sections you will see that
+there are actually a couple of mechanism that do so. Often new features like this
+are built in stepwise and enabled locally for a while and when they seem okay
+they get enabled by default. \footnote {For this we have \type
+{\enableexperiments} which one can use in \type {cont-loc.mkxl} or \type
+{cont-exp.mkxl}, files that are loaded runtime when on the system. When you use
+them, make sure they don't interfere; they are not part of the updates, contrary
+to \type {cont-new.mkxl}.}
+
+\stopsection
+
+\startsection[title=Paragraphs]
+
+Before we demonstrate some trickery, let's see what a paragraph is. Normally a
+document source is formatted like this:
+
+\starttyping[option=TEX]
+some text (line 1)
+some text (line 2)
+
+some more test (line 1)
+some more test (line 2)
+\stoptyping
+
+There are two blocks of text here separated by an empty line and they become two
+paragraphs. Unless configured otherwise an empty line is an indication that we
+end a paragraph. You can also explicitly do that:
+
+\starttyping[option=TEX]
+some text (line 1)
+some text (line 2)
+\par
+some more test (line 1)
+some more test (line 2)
+\stoptyping
+
+When \TEX\ starts a paragraph, it actually also does something think of:
+
+\starttyping[option=TEX]
+[\the\everypar]some text (line 1) some text (line 2) \par
+[\the\everypar]some more test (line 1) some more test (line 2) \par
+\stoptyping
+
+or more accurate:
+
+\starttyping[option=TEX]
+[\the\everypar]some text some text \par
+[\the\everypar]some more test some more test \par
+\stoptyping
+
+because the end|-|of|-|line character has become a space. As mentioned,
+an empty line is actually the end of a paragraph. But in \LUAMETATEX\
+we can cheat a bit. If we have this:
+
+\startbuffer
+line 1
+
+line 2
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We can do this (watch how we need to permit overloading a primitive when we have
+enabled \type {\overloadmode}):
+
+\startbuffer
+\pushoverloadmode
+\def\linepar{\removeunwantedspaces !\ignorespaces}
+\popoverloadmode
+line 1
+
+line 2
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This comes out as:
+
+\start \getbuffer \stop
+
+I admit that since it got added (as part of some cleanup halfway the overhaul of
+the engine) I never saw a reason to use it, but it is a cheap feature. The \type
+{\linepar} primitive is undefined (\type {\undefined}) by default so no user sees
+it anyway. Just don't use it unless maybe for some pseudo database trickery (I
+considered using it for the database module but it is not needed). In a similar
+fashion, just don't redefine \type {\par}: it's asking for troubles and \quote
+{not done} in \CONTEXT\ anyway.
+
+Back to reality. In \LUATEX\ we get a node list that starts with a so called
+\type {localpar} node and ends with a \type {\parfillskip}. The first node is
+prepended automatically. That list travels through the system: hyphenation,
+applying font properties, break the effectively one line into lines, wrap them
+and add them to a vertical list, etc. Each stage can be intercepted via
+callbacks.
+
+When the paragraph is broken into lines hanging indentation or a so called par
+shape can be applied, and we will see more of that later, here we talk \type
+{\par} and show another \LUAMETATEX\ trick:
+
+\startbuffer
+\def\foo{{\bf test:} \ignorepars}
+
+\foo
+
+line
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The macro typesets some text and then skips to the next paragraph:
+
+\start \getbuffer \stop
+
+Think of this primitive as being a more powerful variant of \type
+{\ignorespaces}. This leaves one aspect: how do we start a paragraph. Technically
+we need to force \TEX\ into so called horizontal mode. When you look at plain
+\TEX\ documents you will notice commands like \type {\noindent} and \type
+{\indent}. In \CONTEXT\ we have more high level variants, for instance we have
+\type {\noindentation}.
+
+A robust way to make sure that you get in horizontal mode is using \type
+{\dontleavehmode} which is a wink to \type {\leavevmode}, a command that you
+should never use in \CONTEXT, so when you come from plain or \LATEX, it's one of
+the commands you should wipe from your memory.
+
+When \TEX\ starts with a paragraph the \type {\everypar} token list is expanded
+and again this is a primitive you should not mess with yourself unless in very
+controlled situations. If you change its content, you're on your own with respect
+to interferences and side effects.
+
+One of the things that \TEX\ does in injecting the indentation. Even when there
+is none, it gets added, not as skip but as an empty horizontal box of a certain
+width. This is easier on the engine when it constructs the paragraph from the one
+liner: starting with a skip demands a bit more testing in the process (a nice
+trick so to say). However, in \CONTEXT\ we enable the \LUAMETATEX\ feature that
+does use a skip instead of a box. It's part of the normalization that is
+discussed later. Instead of checking for a box with property indent, we check for
+a skip with such property. This is often easier and cleaner.
+
+A bit off topic is the fact that in traditional \TEX\ empty lines or \type {\par}
+primitives can trigger an error. This has to do with the fact that the program
+evolved in a time where paper terminals were used and runtime could be excessive.
+So, in order to catch a possible missing brace, a concept of \type {\long}
+macros, permitting \type {\par} or equivalents in arguments, was introduced as
+well as not permitting them in for instance display math. In \CONTEXT\ \MKII\
+most macros that could be sensitive for this were defined as \type {\long} so
+that users never had to bother about it and probably were not even aware of it.
+Right from the start in \LUATEX\ these error|-|triggers could be disabled which
+of course we enable in \CONTEXT\ and in \LUAMETATEX\ these features have been
+removed altogether. I don't think users will complain about this.
+
+If you want to enforce a newline but not a new paragraph you can use the \type
+{\crlf} command. When used on its own it will produce an empty line. Don't use
+this to create whitespace between lines.
+
+If you want to do something after so called par tokens are seen you can do this:
+
+\startbuffer
+\def\foo{{\bf >>>> }}
+\expandafterpars\foo
+
+this is a new paragraph ...
+
+\expandafterpars\foo
+\par\par\par\par
+this is a new paragraph ...
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This not to be confused with \type {\everypar} which is a token list that \TEX\
+itself injects before each paragraph (also nested ones).
+
+\getbuffer
+
+This is typically a primitive that will only be used in macros. You can actually
+program it using macros: pickup a token, check and push it back when it's not a
+par equivalent token. The primitive is is just nicer (and easier on the log when
+tracing is enabled).
+
+\stopsection
+
+\startsection[title=Properties]
+
+A paragraph is just a collection of lines that result from one input line that
+got broken. This process of breaking into lines is influenced by quite some
+parameters. In traditional \TEX\ and also in \LUAMETATEX\ by default the values
+that are in effect when the end of the paragraph is met are used. So, when you
+change them in a group and then ends the paragraph after the group, the values
+you've set in the group are not used.
+
+However, in \LUAMETATEX\ we can optionally store them with the paragraph. When
+that happens the values current at the start are frozen. You can still overload
+them but that has to be done explicitly then. The advantage is that grouping no
+longer interferes with the line break algorithm. The magic primitive is \type
+{\snapshotpar} which takes a number made from categories mentioned below:
+
+\starttabulate[|l|l|r|]
+\BC variable \BC category \BC code \NC \NR
+\NC \type {\hsize} \NC hsize \NC 0x\uchexnumbers\frozenhsizecode \NC \NR
+\NC \type {\leftskip} \NC skip \NC 0x\uchexnumbers\frozenskipcode \NC \NR
+\NC \type {\rightskip} \NC skip \NC 0x\uchexnumbers\frozenskipcode \NC \NR
+\NC \type {\hangindent} \NC hang \NC 0x\uchexnumbers\frozenhangcode \NC \NR
+\NC \type {\hangafter} \NC hang \NC 0x\uchexnumbers\frozenhangcode \NC \NR
+\NC \type {\parindent} \NC indent \NC 0x\uchexnumbers\frozenindentcode \NC \NR
+\NC \type {\parfillleftskip} \NC par fill \NC 0x\uchexnumbers\frozenparfillcode \NC \NR
+\NC \type {\parfillrightskip} \NC par fill \NC 0x\uchexnumbers\frozenparfillcode \NC \NR
+\NC \type {\adjustspacing} \NC adjust \NC 0x\uchexnumbers\frozenadjustcode \NC \NR
+\NC \type {\adjustspacingstep} \NC adjust \NC 0x\uchexnumbers\frozenadjustcode \NC \NR
+\NC \type {\adjustspacingshrink} \NC adjust \NC 0x\uchexnumbers\frozenadjustcode \NC \NR
+\NC \type {\adjustspacingstretch} \NC adjust \NC 0x\uchexnumbers\frozenadjustcode \NC \NR
+\NC \type {\protrudechars} \NC protrude \NC 0x\uchexnumbers\frozenprotrudecode \NC \NR
+\NC \type {\pretolerance} \NC tolerance \NC 0x\uchexnumbers\frozentolerancecode \NC \NR
+\NC \type {\tolerance} \NC tolerance \NC 0x\uchexnumbers\frozentolerancecode \NC \NR
+\NC \type {\emergencystretch} \NC stretch \NC 0x\uchexnumbers\frozenstretchcode \NC \NR
+\NC \type {\looseness} \NC looseness \NC 0x\uchexnumbers\frozenloosenesscode \NC \NR
+\NC \type {\lastlinefit} \NC last line \NC 0x\uchexnumbers\frozenlastlinecode \NC \NR
+\NC \type {\linepenalty} \NC line penalty \NC 0x\uchexnumbers\frozenlinepenaltycode \NC \NR
+\NC \type {\interlinepenalty} \NC line penalty \NC 0x\uchexnumbers\frozenlinepenaltycode \NC \NR
+\NC \type {\interlinepenalties} \NC line penalty \NC 0x\uchexnumbers\frozenlinepenaltycode \NC \NR
+\NC \type {\clubpenalty} \NC club penalty \NC 0x\uchexnumbers\frozenclubpenaltycode \NC \NR
+\NC \type {\clubpenalties} \NC club penalty \NC 0x\uchexnumbers\frozenclubpenaltycode \NC \NR
+\NC \type {\widowpenalty} \NC widow penalty \NC 0x\uchexnumbers\frozenwidowpenaltycode \NC \NR
+\NC \type {\widowpenalties} \NC widow penalty \NC 0x\uchexnumbers\frozenwidowpenaltycode \NC \NR
+\NC \type {\displaywidowpenalty} \NC display penalty \NC 0x\uchexnumbers\frozendisplaypenaltycode \NC \NR
+\NC \type {\displaywidowpenalties} \NC display penalty \NC 0x\uchexnumbers\frozendisplaypenaltycode \NC \NR
+\NC \type {\brokenpenalty} \NC broken penalty \NC 0x\uchexnumbers\frozenbrokenpenaltycode \NC \NR
+\NC \type {\adjdemerits} \NC demerits \NC 0x\uchexnumbers\frozendemeritscode \NC \NR
+\NC \type {\doublehyphendemerits} \NC demerits \NC 0x\uchexnumbers\frozendemeritscode \NC \NR
+\NC \type {\finalhyphendemerits} \NC demerits \NC 0x\uchexnumbers\frozendemeritscode \NC \NR
+\NC \type {\parshape} \NC shape \NC 0x\uchexnumbers\frozenshapecode \NC \NR
+\NC \type {\baselineskip} \NC line \NC 0x\uchexnumbers\frozenlinecode \NC \NR
+\NC \type {\lineskip} \NC line \NC 0x\uchexnumbers\frozenlinecode \NC \NR
+\NC \type {\lineskiplimit} \NC line \NC 0x\uchexnumbers\frozenlinecode \NC \NR
+\NC \type {\hyphenationmode} \NC hyphenation \NC 0x\uchexnumbers\frozenhyphenationcode \NC \NR
+\stoptabulate
+
+
+As you can see here, there are more paragraph related parameters than in for
+instance \PDFTEX\ and \LUATEX\ and these are (to be) explained in the
+\LUAMETATEX\ manual. You can imagine that keeping this around with the paragraph
+adds some extra overhead to the machinery but most users won't notice that
+because is is compensated by gains elsewhere.
+
+This is pretty low level and there are a bunch of helpers that support this but
+these are not really user level macros. As with everything \TEX\ you can mess
+around as much as you like, and the code gives plenty of examples but when you do
+this, you're on your own because it can interfere with \CONTEXT\ core
+functionality.
+
+In \LMTX\ taking these snapshots is turned on by default and because it thereby
+fundamentally influences the par builder, users can run into compatibility issues
+but in practice there has been no complaints (and this feature has been in use
+quite a while before this document was written). One reason for users not
+noticing is that one of the big benefits is probably handled by tricks mentioned
+on the mailing list. Imagine that you have this:
+
+\starttyping[option=TEX]
+{\bf watch out:} here is some text
+\stoptyping
+
+In this small example the result will be as expected. But what if something magic
+with the start of a paragraph is done? Like this:
+
+\starttyping[option=TEX]
+\placefigure[left]{A cow!}{\externalfigure[cow.pdf]}
+
+{\bf watch out:} here is some text ... of course much more is needed to
+ get a flow around the figure!
+\stoptyping
+
+The figure will hang at the left side of the paragraph but it is put there when
+the text starts and that happens inside the bold group. It means that the
+properties we set in order to get the shape around the figure are lost as soon as
+we're at \quote{\type {here is some text}} and definitely is wrong when the
+paragraph ends and the par builder has to use them to get the shape right. We get
+text overlapping the figure. A trick to overcome this is:
+
+\starttyping[option=TEX]
+\dontleavehmode {\bf watch out:} here is some text ... of course much
+ more is needed to get a flow around the figure!
+\stoptyping
+
+where the first macro makes sure we already start a paragraph before the group is
+entered (using a \type {\strut} also works). It's not nice and I bet users have
+been bitten by this and by now know the tricks. But, with snapshots such fuzzy
+hacks are not needed any more! The same is true with this:
+
+\starttyping[option=TEX]
+{\leftskip 1em some text \par}
+\stoptyping
+
+where we had to explicitly end the paragraph inside the group in order to retain
+the skip. I suppose that users normally use the high level environments so they
+never had to worry about this. It's also why users probably won't notice that
+this new mechanism has been active for a while. Actually, when you now change a
+parameter inside the paragraph its new value will not be applied (unless you
+prefix it with \type {\frozen} or snapshot it) but no one did that anyway.
+
+\stopsection
+
+\startsection[title=Wrapping up]
+
+In \CONTEXT\ \LMTX\ we have a mechanism to exercise macros (or content) before a
+paragraph ends. This is implemented using the \type {\wrapuppar} primitive. The
+to be wrapped up material is bound to the current paragraph which in order to
+get this done has to be started when this primitive is used.
+
+Although the high level interface has been around for a while it still needs a
+bit more testing (read: use cases are needed). In the few cases where we already
+use it application can be different because again it relates to snapshots. This
+because in the past we had to use tricks that also influenced the user interface
+of some macros (which made them less natural as one would expect). So the
+question is: where do we apply it in old mechanisms and where not.
+
+{\em todo: accumulation, interference, where applied, limitations}
+
+% \vbox {vbox : \wrapuppar{1}test\par x\wrapuppar{2}test}\blank
+% \vtop {vtop : \wrapuppar{1}test\par x\wrapuppar{2}test}\blank
+% \vcenter{vcenter : \wrapuppar{1}test\par x\wrapuppar{2}test}\blank
+% $$x = \vcenter{vcenter : \wrapuppar{1}test\par x\wrapuppar{2}test}$$\blank
+% x\vadjust{vadjust : \wrapuppar{1}test\par x\wrapuppar{2}test}x\blank
+
+\stopsection
+
+\startsection[title=Hanging]
+
+There are two mechanisms for getting a specific paragraph shape: rectangular
+hanging and arbitrary shapes. Both mechanisms work top|-|down. The first
+mechanism uses a combination of \type {\hangafter} and \type {\hangindent}, and
+the second one depends on \type {\parshape}. In this section we discuss the
+rectangular one.
+
+\startbuffer[demo-5]
+\hangafter 4 \hangindent 4cm \samplefile{tufte} \page
+\hangafter -4 \hangindent 4cm \samplefile{tufte} \page
+\hangafter 4 \hangindent -4cm \samplefile{tufte} \page
+\hangafter -4 \hangindent -4cm \samplefile{tufte} \page
+\stopbuffer
+
+\typebuffer[demo-5][option=TEX]
+
+As you can see in \in {figure} [fig:hang], the four cases are driven by the sign
+of the values. If you want to hang into the margin you need to use different
+tricks, like messing with the \type {\leftskip}, \type {\rightskip} or \type
+{\parindent} parameters (which then of course can interfere with other mechanisms
+uses at the same time).
+
+\startplacefigure[title=Hanging indentation,reference=fig:hang]
+\startcombination[nx=2,ny=2]
+ {\typesetbuffer[demo-5][page=1,width=.4\textwidth,frame=on]} {\type{\hangafter +4 \hangindent +4cm}}
+ {\typesetbuffer[demo-5][page=2,width=.4\textwidth,frame=on]} {\type{\hangafter -4 \hangindent +4cm}}
+ {\typesetbuffer[demo-5][page=3,width=.4\textwidth,frame=on]} {\type{\hangafter +4 \hangindent -4cm}}
+ {\typesetbuffer[demo-5][page=4,width=.4\textwidth,frame=on]} {\type{\hangafter -4 \hangindent -4cm}}
+\stopcombination
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=Shapes]
+
+In \CONTEXT\ we don't use \type {\parshape} a lot. It is used in for instance
+side floats but even there not in all cases. It's more meant for special
+applications. This means that in \MKII\ and \MKIV\ we don't have some high level
+interface. However, when \METAFUN\ got upgraded to \LUAMETAFUN, and the manual
+also needed an update, one of the examples in that manual that used shapes also
+got done differently (read: nicer). And that triggered the arrival of a new low
+level shape mechanism.
+
+One important property of the \type {\parshape} mechanism is that it works per
+paragraph. You define a shape in terms of a left margin and width of a line. The
+shape has a fixed number of such pairs and when there is more content, the last
+one is used for the rest of the lines. When the paragraph is finished, the shape
+is forgotten. \footnote {Not discussed here is a variant that might end up in
+\LUAMETATEX\ that works with the progression, i.e.\ takes the height of the
+content so far into account. This is somewhat tricky because for that to work
+vertical skips need to be frozen, which is no real big deal but has to be done
+careful in the code.}
+
+The high level interface is a follow up on the example in the \METAFUN\ manual and
+uses shapes that carry over to the next paragraph. In addition we can cycle over
+a shape. In this interface shapes are defined using keyword. Here are some
+examples:
+
+\starttyping[option=TEX]
+\startparagraphshape[test]
+ left 1mm right 1mm
+ left 5mm right 5mm
+\stopparagraphshape
+\stoptyping
+
+This shape has only two entries so the first line will have a 1mm margin while
+later lines will get 5mm margins. This translates into a \type {\parshape} like:
+
+\starttyping[option=TEX]
+\parshape 2
+ 1mm \dimexpr\hsize-1mm\relax
+ 5mm \dimexpr\hsize-5mm\relax
+\stoptyping
+
+Watch the number \type {2}: it tells how many specification lines follow. As you
+see, we need to calculate the width.
+
+\starttyping[option=TEX]
+\startparagraphshape[test]
+ left 1mm right 1mm
+ left 5mm right 5mm
+ repeat
+\stopparagraphshape
+\stoptyping
+
+This variant will alternate between 1mm and 5mm margins. The repeating feature is
+translated as follows. Maybe at some point I will introduce a few more options.
+
+\starttyping[option=TEX]
+\parshape 2 options 1
+ 1mm \dimexpr\hsize-1mm\relax
+ 5mm \dimexpr\hsize-5mm\relax
+\stoptyping
+
+A shape can have some repetition, and we can save keystrokes by copying the last
+entry. The resulting \type {\parshape} becomes rather long.
+
+\starttyping[option=TEX]
+\startparagraphshape[test]
+ left 1mm right 1mm
+ left 2mm right 2mm
+ left 3mm right 3mm
+ copy 8
+ left 4mm right 4mm
+ left 5mm right 5mm
+ left 5mm hsize 10cm
+\stopparagraphshape
+\stoptyping
+
+Also watch the \type {hsize} keyword: we don't calculate the hsize from the \type
+{left} and \type {right} values but explicitly set it.
+
+\starttyping[option=TEX]
+\startparagraphshape[test]
+ left 1mm right 1mm
+ right 3mm
+ left 5mm right 5mm
+ repeat
+\stopparagraphshape
+\stoptyping
+
+When a \type {right} keywords comes first the \type {left} is assumed to be zero.
+In the examples that follow we will use a couple of definitions:
+
+\startbuffer[setup-0]
+\startparagraphshape[test]
+ both 1mm both 2mm both 3mm both 4mm both 5mm both 6mm
+ both 7mm both 6mm both 5mm both 4mm both 3mm both 2mm
+\stopparagraphshape
+\stopbuffer
+
+\startbuffer[setup-0-repeat]
+\startparagraphshape[test-repeat]
+ both 1mm both 2mm both 3mm both 4mm both 5mm both 6mm
+ both 7mm both 6mm both 5mm both 4mm both 3mm both 2mm
+ repeat
+\stopparagraphshape
+\stopbuffer
+
+\typebuffer[setup-0,setup-0-repeat][option=TEX]
+
+The last one could also be defines as:
+
+\starttyping[option=TEX]
+\startparagraphshape[test-repeat]
+ \rawparagraphshape{test} repeat
+\stopparagraphshape
+\stoptyping
+
+In the previous code we already introduced the \type {repeat} option. This will
+make the shape repeat at the engine level when the shape runs out of specified
+lines. In the application of a shape definition we can specify a \type {method}
+to be used and that determine if the next paragraph will start where we left off
+and discard afterwards (\type {shift}) or that we move the discarded lines up
+front so that we never run out of lines (\type {cycle}). It sounds complicated
+but just keep in mind that \type {repeat} is part of the \type {\parshape} and
+act within a paragraph while \type {shift} and \type {cycle} are applied when a
+new paragraph is started.
+
+\startbuffer[demo-1]
+\startshapedparagraph[list=test]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\startbuffer[demo-1-repeat]
+\startshapedparagraph[list=test-repeat]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+In \in {figure} [fig:shape:discard] you see the following applied:
+
+\typebuffer[demo-1,demo-1-repeat][option=TEX]
+
+\startplacefigure[title=Discarded shaping,reference=fig:shape:discard]
+\startcombination[nx=2,ny=2]
+ {\typesetbuffer[setup-0,demo-1] [page=1,width=.4\textwidth,frame=on]} {discard, finite shape, page 1}
+ {\typesetbuffer[setup-0,demo-1] [page=2,width=.4\textwidth,frame=on]} {discard, finite shape, page 2}
+ {\typesetbuffer[setup-0,demo-1-repeat][page=1,width=.4\textwidth,frame=on]} {discard, repeat in shape, page 1}
+ {\typesetbuffer[setup-0,demo-1-repeat][page=2,width=.4\textwidth,frame=on]} {discard, repeat in shape, page 2}
+\stopcombination
+\stopplacefigure
+
+In \in {figure} [fig:shape:shift] we use this instead:
+
+\startbuffer[demo-2]
+\startshapedparagraph[list=test,method=shift]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\startbuffer[demo-2-shift]
+\startshapedparagraph[list=test-repeat,method=shift]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\typebuffer[demo-2,demo-2-repeat][option=TEX]
+
+\startplacefigure[title=Shifted shaping,reference=fig:shape:shift]
+\startcombination[nx=2,ny=2]
+ {\typesetbuffer[setup-0,demo-2][page=1,width=.4\textwidth,frame=on]} {shift, finite shape, page 1}
+ {\typesetbuffer[setup-0,demo-2][page=2,width=.4\textwidth,frame=on]} {shift, finite shape, page 2}
+ {\typesetbuffer[setup-0-repeat,demo-2-shift][page=1,width=.4\textwidth,frame=on]} {shift, repeat in shape, page 1}
+ {\typesetbuffer[setup-0-repeat,demo-2-shift][page=2,width=.4\textwidth,frame=on]} {shift, repeat in shape, page 2}
+\stopcombination
+\stopplacefigure
+
+Finally, in \in {figure} [fig:shape:cycle] we use:
+
+\startbuffer[demo-3]
+\startshapedparagraph[list=test,method=cycle]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\startbuffer[demo-3-cycle]
+\startshapedparagraph[list=test-repeat,method=cycle]
+ \dorecurse{8}{\showparagraphshape\samplefile{tufte} \par}
+\stopshapedparagraph
+\stopbuffer
+
+\typebuffer[demo-3,demo-3-repeat][option=TEX]
+
+\startplacefigure[title=Cycled shaping,reference=fig:shape:cycle]
+\startcombination[nx=2,ny=2]
+ {\typesetbuffer[setup-0,demo-3][page=1,width=.4\textwidth,frame=on]} {cycle, finite shape, page 1}
+ {\typesetbuffer[setup-0,demo-3][page=2,width=.4\textwidth,frame=on]} {cycle, finite shape, page 2}
+ {\typesetbuffer[setup-0-repeat,demo-3-cycle][page=1,width=.4\textwidth,frame=on]} {cycle, repeat in shape, page 1}
+ {\typesetbuffer[setup-0-repeat,demo-3-cycle][page=2,width=.4\textwidth,frame=on]} {cycle, repeat in shape, page 2}
+\stopcombination
+\stopplacefigure
+
+These examples are probably too small to see the details but you can run them
+yourself or zoom in on the details. In the margin we show the values used. Here
+is a simple example of (non) poetry. There are other environments that can be
+used instead but this makes a good example anyway.
+
+\startbuffer
+\startparagraphshape[test]
+ left 0em right 0em
+ left 1em right 0em
+ repeat
+\stopparagraphshape
+
+\startshapedparagraph[list=test,method=cycle]
+ verse line 1.1\crlf verse line 2.1\crlf
+ verse line 3.1\crlf verse line 4.1\par
+ verse line 1.2\crlf verse line 2.2\crlf
+ verse line 3.2\crlf verse line 4.2\crlf
+ verse line 5.2\crlf verse line 6.2\par
+\stopshapedparagraph
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\start \getbuffer \stop
+
+Because the idea for this feature originates in \METAFUN, we will now kick in
+some \METAPOST. The following code creates a shape for a circle. We use a
+2mm offset here:
+
+\startbuffer
+\startuseMPgraphic{circle}
+ path p ; p := fullcircle scaled TextWidth ;
+ build_parshape(p,
+ 2mm, 0, 0,
+ LineHeight, StrutHeight, StrutDepth, StrutHeight
+ ) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\start \getbuffer \stop
+
+We plug this into the already described macros:
+
+\startbuffer
+\startshapedparagraph[mp=circle]%
+ \setupalign[verytolerant,stretch,last]%
+ \samplefile{tufte}
+ \samplefile{tufte}
+\stopshapedparagraph
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+And get ourself a circular shape. Watch out, at this moment the shape environment
+does not add grouping so when as in this case you change the alignment it can
+influence the document.
+
+\start \getbuffer \stop
+
+\startbuffer[framed]
+\framed[align=normal,width=\textwidth,offset=2mm,strut=no]\bgroup
+ \getbuffer
+\egroup
+\stopbuffer
+
+Assuming that the shape definition above is in a buffer we can do this:
+
+\typebuffer[option=TEX]
+
+The result is shown in \in {figure} [fig:shape:circle]. Because all action
+happens in the framed environment, we can also use this definition:
+
+\starttyping[option=TEX]
+\startuseMPgraphic{circle}
+ path p ; p := fullcircle scaled \the\dimexpr\framedwidth+\framedoffset*2\relax ;
+ build_parshape(p,
+ \framedoffset, 0, 0,
+ LineHeight, StrutHeight, StrutDepth, StrutHeight
+ ) ;
+ draw p ;
+\stopuseMPgraphic
+\stoptyping
+
+\startplacefigure[title=A framed circular shape,reference=fig:shape:circle]
+ \getbuffer[framed]
+\stopplacefigure
+
+A mechanism like this is often never completely automatic in the sense that you
+need to keep an eye on the results. Depending on user demands more features can
+be added. With weird shapes you might want to set up the alignment to be \type
+{tolerant} and have some \type {stretch}.
+
+The interface described in the \METAFUN\ manual is pretty old, the time stamp of
+the original code is mid 2000, but the principles didn't change. The examples in
+\type {meta-imp-txt.mkxl} can now be written as:
+
+\startuseMPgraphic{test 1}
+ begingroup ;
+ save p ; path p ; p := fullcircle scaled 6cm ;
+ lmt_parshape [
+ path = p,
+ offset = BodyFontSize/2,
+ dx = 0, % default
+ dy = 0, % default
+ lineheight = LineHeight, % default
+ strutheight = StrutHeight, % default
+ strutdepth = StrutDepth, % default
+ topskip = StrutHeight, % default
+ ] ;
+ draw p withpen pencircle scaled 1pt ;
+ endgroup ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{test 2}
+ begingroup ;
+ save p ; path p ; p := fullsquare rotated 45 scaled 5cm ;
+ lmt_parshape [
+ path = p,
+ offset = BodyFontSize/2,
+ trace = true,
+ ] ;
+ draw p withpen pencircle scaled 1pt ;
+ endgroup ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{test 3}
+ begingroup ;
+ save w, h, p ; path p ; w := h := 6cm ;
+ p := (.5w,h) -- ( 0, h) -- (0,0) -- (w,0) &
+ ( w,0) .. (.75w,.5h) .. (w,h) & (w,h) -- cycle ;
+ lmt_parshape [
+ path = p,
+ offset = BodyFontSize/2,
+ ] ;
+ draw p withpen pencircle scaled 1pt ;
+ endgroup ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{test 4}
+ begingroup ;
+ save d, p, q ; path p, q ; d := BodyFontSize/2;
+ vardef shape(expr w, h, o) =
+ (o,o) -- (w-o,o) & (w-o,o) .. (.75w-o,.5h) ..
+ (w-2o,h-o) & (w-2o,h-o) -- (o,h-o) -- cycle
+ enddef ;
+ p := shape(6cm, 6cm, d) ; q := shape(6cm, 6cm, 0) ;
+ lmt_parshape [
+ path = p,
+ offsetpath = q,
+ dx = d,
+ dy = d,
+ trace = true,
+ ] ;
+ draw q withpen pencircle scaled 1pt ;
+ endgroup ;
+\stopuseMPgraphic
+
+\defineoverlay[test 1][\useMPgraphic{test 1}]
+\defineoverlay[test 2][\useMPgraphic{test 2}]
+\defineoverlay[test 3][\useMPgraphic{test 3}]
+\defineoverlay[test 4][\useMPgraphic{test 4}]
+
+\startbuffer
+ \startshapetext[test 1,test 2,test 3,test 4]
+ \setupalign[verytolerant,stretch,normal]%
+ \samplefile{douglas} % Douglas R. Hofstadter
+ \stopshapetext
+ \startcombination[2*2]
+ {\framed[offset=overlay,frame=off,background=test 1]{\getshapetext}}
+ {test 1}
+ {\framed[offset=overlay,frame=off,background=test 2]{\getshapetext}}
+ {test 2}
+ {\framed[offset=overlay,frame=off,background=test 3]{\getshapetext}}
+ {test 3}
+ {\framed[offset=overlay,frame=off,background=test 4]{\getshapetext}}
+ {test 4}
+ \stopcombination
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+In \in {figure} [fig:shapes:chain] we see the result. Watch how for two shapes
+we have enabled tracing. Of course you need to tweak till all fits well but we're
+talking of special situations anyway.
+
+\startplacefigure[Title=Multiple shapes,reference=fig:shapes:chain]
+ \getbuffer
+\stopplacefigure
+
+Here is a bit more extreme example. Again we use a circle:
+
+\startbuffer
+\startuseMPgraphic{circle}
+ lmt_parshape [
+ path = fullcircle scaled 136mm,
+ offset = 2mm,
+ bottomskip = - 1.5LineHeight,
+ ] ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+But we output a longer text:
+
+\startbuffer
+\startshapedparagraph[mp=circle,repeat=yes,method=cycle]%
+ \setupalign[verytolerant,stretch,last]\dontcomplain
+ {\darkred \samplefile{tufte}}\par
+ {\darkgreen \samplefile{tufte}}\par
+ {\darkblue \samplefile{tufte}}\par
+ {\darkcyan \samplefile{tufte}}\par
+ {\darkmagenta \samplefile{tufte}}\par
+\stopshapedparagraph
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get a multi|-|page shape:
+
+\start \getbuffer \stop
+
+Compare this with:
+
+\startbuffer
+\startshapedparagraph[mp=circle,repeat=yes,method=cycle]%
+ \setupalign[verytolerant,stretch,last]\dontcomplain
+ {\darkred \samplefile{tufte}}
+ {\darkgreen \samplefile{tufte}}
+ {\darkblue \samplefile{tufte}}
+ {\darkcyan \samplefile{tufte}}
+ {\darkmagenta \samplefile{tufte}}
+\stopshapedparagraph
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Which gives:
+
+\start \getbuffer \stop
+
+Here the \type {bottomskip} takes care of subtle rounding issues as well as
+discarding the last line in the shape so that we get nicer continuation. There is
+no full automated solution for all you can come up with.
+
+Mixing a \METAPOST\ specification into a regular one is also possible. The next
+example demonstrates this as well as the option to remove some lines from a
+specification:
+
+\starttyping[option=TEX]
+\startparagraphshape[test]
+ left 0em right 0em
+ left 1em right 0em
+ metapost {circle}
+ delete 3
+ metapost {circle,circle,circle}
+ delete 7
+ metapost {circle}
+ repeat
+\stopparagraphshape
+\stoptyping
+
+You can combine a shape with narrowing a paragraph. Watch the \type {absolute}
+keyword in the next code. The result is shown in \in {figure} [fig:shape:skips].
+
+\startbuffer[demo-4]
+\startuseMPgraphic{circle}
+ lmt_parshape [
+ path = fullcircle scaled TextWidth,
+ bottomskip = - 1.5LineHeight,
+ ] ;
+\stopuseMPgraphic
+
+\startparagraphshape[test-1]
+ metapost {circle} repeat
+\stopparagraphshape
+
+\startparagraphshape[test-2]
+ absolute left metapost {circle} repeat
+\stopparagraphshape
+
+\startparagraphshape[test-3]
+ absolute right metapost {circle} repeat
+\stopparagraphshape
+
+\startparagraphshape[test-4]
+ absolute both metapost {circle} repeat
+\stopparagraphshape
+
+\showframe
+
+\startnarrower[4*left,2*right]
+ \startshapedparagraph[list=test-1,repeat=yes,method=repeat]%
+ \setupalign[verytolerant,stretch,last]\dontcomplain
+ \dorecurse{3}{\samplefile{thuan}}
+ \stopshapedparagraph
+ \page
+ \startshapedparagraph[list=test-2,repeat=yes,method=repeat]%
+ \setupalign[verytolerant,stretch,last]\dontcomplain
+ \dorecurse{3}{\samplefile{thuan}}
+ \stopshapedparagraph
+ \page
+ \startshapedparagraph[list=test-3,repeat=yes,method=repeat]%
+ \setupalign[verytolerant,stretch,last]\dontcomplain
+ \dorecurse{3}{\samplefile{thuan}}
+ \stopshapedparagraph
+ \page
+ \startshapedparagraph[list=test-4,repeat=yes,method=repeat]%
+ \setupalign[verytolerant,stretch,last]\dontcomplain
+ \dorecurse{3}{\samplefile{thuan}}
+ \stopshapedparagraph
+\stopnarrower
+\stopbuffer
+
+\typebuffer[demo-4][option=TEX]
+
+\startplacefigure[title=Skip compensation,reference=fig:shape:skips]
+\startcombination[nx=2,ny=2]
+ {\typesetbuffer[demo-4][page=1,width=.4\textwidth,frame=on]} {test 1}
+ {\typesetbuffer[demo-4][page=2,width=.4\textwidth,frame=on]} {test 2, left}
+ {\typesetbuffer[demo-4][page=3,width=.4\textwidth,frame=on]} {test 3, right}
+ {\typesetbuffer[demo-4][page=4,width=.4\textwidth,frame=on]} {test 4, both}
+\stopcombination
+\stopplacefigure
+
+\stopsection
+
+% \startsection[title=Linebreaks]
+\startsection[title=Modes]
+
+% \ruledvbox{1\ifhmode\writestatus{!}{HMODE 1}\fi} % hsize
+% \ruledvbox{\hbox{\strut 2}\ifhmode\writestatus{!}{HMODE 2}\fi} % fit
+% \ruledvbox{\hbox{\strut 3}\hbox{\strut 3}\ifhmode\writestatus{!}{HMODE 3}\fi} % fit
+% \ruledvbox{\hbox{\strut 4}4\ifhmode\writestatus{!}{HMODE 4}\fi} % hsize
+% \ruledvbox{\hbox{\strut 5}5\hbox{\strut 5}\ifhmode\writestatus{!}{HMODE 5}\fi} % hsize
+% \ruledvbox{6\hbox{\strut 6}\ifhmode\writestatus{!}{HMODE 6}\fi} % hsize
+
+{\em todo: some of the side effects of so called modes}
+
+\stopsection
+
+\startsection[title=Normalization]
+
+{\em todo: users don't need to bother about this but it might be interesting anyway}
+
+\stopsection
+
+\stopdocument
+
+\everyhbox \everyvbox : useless unless one resets
+\parattr
+\snapshotpar
+\wrapuppar
+
+% \parfillleftskip
+
+% I rewarded myself after writing a section by watching the video "Final Thing On
+% My Mind", The Pineapple This, Live, 2020, the usual perfect GH performance,
+% wondering if live would turn to normal so that we could go to such concerts once
+% again given successive covids. Writing manuals can do with a distraction.
+%
+% Gavin Harrison: Soundcheck, Drummerworld Jan 27, 2021 ... I wish I could make
+% something called a check into pefect solo. Okay, another section and I'll check
+% out the latest Simon Phillips and other favourite dummer uploads.
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-scope.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-scope.tex
new file mode 100644
index 00000000000..1313de92332
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-scope.tex
@@ -0,0 +1,341 @@
+% language=us
+
+% \hfil \hss
+% spread
+
+\environment lowlevel-style
+
+\startdocument
+ [title=scope,
+ color=middleblue]
+
+\startsection[title=Introduction]
+
+When I visited the file where register allocations are implemented I wondered to
+what extend it made sense to limit allocation to global instances only. This
+chapter deals with this phenomena.
+
+\stopsection
+
+\startsection[title=Registers]
+
+In \TEX\ definitions can be local or global. Most assignments are local within a
+group. Registers and definitions can be assigned global by using the \type
+{\global} prefix. There are also some properties that are global by design, like
+\type {\prevdepth}. A mixed breed are boxes. When you tweak its dimensions you
+actually tweak the current box, which can be an outer level. Compare:
+
+\starttyping[option=TEX]
+\scratchcounter = 1
+here the counter has value 1
+\begingroup
+ \scratchcounter = 2
+ here the counter has value 2
+\endgroup
+here the counter has value 1
+\stoptyping
+
+with:
+
+\starttyping[option=TEX]
+\setbox\scratchbox=\hbox{}
+here the box has zero width
+\begingroup
+ \wd\scratchbox=10pt
+ here the box is 10pt wide
+\endgroup
+here the box is 10pt wide
+\stoptyping
+
+It all makes sense so a remark like \quotation {Assignments to box dimensions are
+always global} are sort of confusing. Just look at this:
+
+\startbuffer
+\setbox\scratchbox=\hbox to 20pt{}
+here the box is \the\wd\scratchbox\ wide\par
+\begingroup
+ \setbox\scratchbox=\hbox{}
+ here the box is \the\wd\scratchbox\ wide\par
+ \begingroup
+ \wd\scratchbox=15pt
+ here the box is \the\wd\scratchbox\ wide\par
+ \endgroup
+ here the box is \the\wd\scratchbox\ wide\par
+\endgroup
+here the box is \the\wd\scratchbox\ wide\par
+\stopbuffer
+
+\typebuffer[option=TEX] \startlines \getbuffer \stoplines
+
+If you don't think about it, what happens is what you expect. Now watch the next
+variant:
+
+\startbuffer
+\setbox\scratchbox=\hbox to 20pt{}
+here the box is \the\wd\scratchbox\ wide\par
+\begingroup
+ \setbox\scratchbox=\hbox{}
+ here the box is \the\wd\scratchbox\ wide\par
+ \begingroup
+ \global\wd\scratchbox=15pt
+ here the box is \the\wd\scratchbox\ wide\par
+ \endgroup
+ here the box is \the\wd\scratchbox\ wide\par
+\endgroup
+here the box is \the\wd\scratchbox\ wide\par
+\stopbuffer
+
+The \type {\global} is only effective for the current box. It is good to realize
+that when we talk registers, the box register behaves just like any other
+register but the manipulations happen to the current one.
+
+\typebuffer \startlines \getbuffer \stoplines
+
+\startbuffer
+\scratchdimen=20pt
+here the dimension is \the\scratchdimen\par
+\begingroup
+ \scratchdimen=0pt
+ here the dimension is \the\scratchdimen\par
+ \begingroup
+ \global\scratchdimen=15pt
+ here the dimension is \the\scratchdimen\par
+ \endgroup
+ here the dimension is \the\scratchdimen\par
+\endgroup
+here the dimension is \the\scratchdimen\par
+\stopbuffer
+
+\typebuffer[option=TEX] \startlines \getbuffer \stoplines
+
+\stopsection
+
+\startsection[title=Allocation]
+
+The plain \TEX\ format has set some standards and one of them is that registers
+are allocated with \type {\new...} commands. So we can say:
+
+\starttyping[option=TEX]
+\newcount\mycounta
+\newdimen\mydimena
+\stoptyping
+
+These commands take a register from the pool and relate the given name to that
+entry. In \CONTEXT\ we have a bunch of predefined scratch registers for general
+use, like:
+
+\startbuffer
+scratchcounter : \meaningfull\scratchcounter
+scratchcounterone : \meaningfull\scratchcounterone
+scratchcountertwo : \meaningfull\scratchcountertwo
+scratchdimen : \meaningfull\scratchdimen
+scratchdimenone : \meaningfull\scratchdimenone
+scratchdimentwo : \meaningfull\scratchdimentwo
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The meaning reveals what these are:
+
+\startlines \tttf \getbuffer \stoplines
+
+You can use the numbers directly but that is a bad idea because they can clash!
+In the original \TEX\ engine there are only 256 registers and some are used by
+the engine and the core of a macro package itself, so that leaves a little amount
+for users. The \ETEX\ extension lifted that limitation and bumped to 32K and
+\LUATEX\ upped that to 64K. One could go higher but what makes sense? These
+registers are taking part of the fixed memory slots because that makes nested
+(grouped) usage efficient and access fast. The number you see above is deduced
+from the so called command code (here indicated by \type {\count}) and an index
+encoded in the same token. So, \type {\scratchcounter} takes a single token
+contrary to the verbose \type {\count257} that takes four tokens where the number
+gets parsed every time it is needed. But those are details that a user can
+forget.
+
+As mentioned, commands like \type {\newcount \foo} create a global control
+sequence \type {\foo} referencing a counter. You can locally redefine that
+control sequence unless in \LUAMETATEX\ you have so called overload mode enabled.
+You can do local or global assignments to these registers.
+
+\starttyping[option=TEX]
+\scratchcounter = 123
+\begingroup
+ \scratchcounter = 456
+ \begingroup
+ \global\scratchcounter = 789
+ \endgroup
+\endgroup
+\stoptyping
+
+And in both cases count register 257 is set. When an assignment is global,
+all current values to that register get the same value. Normally this is all
+quite transparent: you get what you ask for. However the drawback is that
+as a user you cannot know what variables are already defined, which means
+that this will fail (that is: it will issue a message):
+
+\starttyping[option=TEX]
+\newcount\scratchcounter
+\stoptyping
+
+as will the second line in:
+
+\starttyping[option=TEX]
+\newcount\myscratchcounter
+\newcount\myscratchcounter
+\stoptyping
+
+In \CONTEXT\ the scratch registers are visible but there are lots of internally
+used ones are protected from the user by more obscure names. So what if you want
+to use your own register names without \CONTEXT\ barking to you about not being
+able to define it. This is why in \LMTX\ (and maybe some day in \MKIV) we now
+have local definitions:
+
+\startbuffer
+\begingroup
+ \newlocaldimen\mydimena \mydimena1\onepoint
+ \newlocaldimen\mydimenb \mydimenb2\onepoint
+ (\the\mydimena,\the\mydimenb)
+ \begingroup
+ \newlocaldimen\mydimena \mydimena3\onepoint
+ \newlocaldimen\mydimenb \mydimenb4\onepoint
+ \newlocaldimen\mydimenc \mydimenc5\onepoint
+ (\the\mydimena,\the\mydimenb,\the\mydimenc)
+ \begingroup
+ \newlocaldimen\mydimena \mydimena6\onepoint
+ \newlocaldimen\mydimenb \mydimenb7\onepoint
+ (\the\mydimena,\the\mydimenb)
+ \endgroup
+ \newlocaldimen\mydimend \mydimend8\onepoint
+ (\the\mydimena,\the\mydimenb,\the\mydimenc,\the\mydimend)
+ \endgroup
+ (\the\mydimena,\the\mydimenb)
+\endgroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The allocated registers get zero values but you can of course set them to any
+value that fits their nature:
+
+\startlines \getbuffer \stoplines
+
+\startbuffer
+\begingroup
+ \setnewlocaldimen\mydimena 1\onepoint
+ \setnewlocaldimen\mydimenb 2\onepoint
+ (\the\mydimena,\the\mydimenb)
+ \begingroup
+ \setnewlocaldimen\mydimena 3\onepoint
+ \setnewlocaldimen\mydimenb 4\onepoint
+ \setnewlocaldimen\mydimenc 5\onepoint
+ (\the\mydimena,\the\mydimenb,\the\mydimenc)
+ \begingroup
+ \setnewlocaldimen\mydimena 6\onepoint
+ \setnewlocaldimen\mydimenb 7\onepoint
+ (\the\mydimena,\the\mydimenb)
+ \endgroup
+ \setnewlocaldimen\mydimend 8\onepoint
+ (\the\mydimena,\the\mydimenb,\the\mydimenc,\the\mydimend)
+ \endgroup
+ (\the\mydimena,\the\mydimenb)
+\endgroup
+\stopbuffer
+
+You can also use the next variant where you also pass the initial value:
+
+\typebuffer[option=TEX]
+
+So, again we get:
+
+\startlines \getbuffer \stoplines
+
+When used in the body of the macro there is of course a little overhead
+involved in the repetitive allocation but normally that can be neglected.
+
+\stopsection
+
+\startsection[title=Files]
+
+When adding these new allocators I also wondered about the read and write
+allocators. We don't use them in \CONTEXT\ but maybe users like them, so let's
+give an example and see what more demands they have:
+
+\starttyping[option=TEX]
+\integerdef\StartHere\numexpr\inputlineno+2\relax
+\starthiding
+SOME LINE 1
+SOME LINE 2
+SOME LINE 3
+SOME LINE 4
+\stophiding
+\integerdef\StopHere\numexpr\inputlineno-2\relax
+\stoptyping
+
+% We need to be in the file!
+
+\integerdef\StartHere\numexpr\inputlineno+2\relax
+\starthiding
+SOME LINE 1
+SOME LINE 2
+SOME LINE 3
+SOME LINE 4
+\stophiding
+\integerdef\StopHere\numexpr\inputlineno-2\relax
+
+\startbuffer
+\begingroup
+ \newlocalread\myreada
+ \immediate\openin\myreada {lowlevel-scope.tex}
+ \dostepwiserecurse{\StopHere}{\StartHere}{-1}{
+ \readline\myreada line #1 to \scratchstring #1 : \scratchstring \par
+ }
+ \blank
+ \dostepwiserecurse{\StartHere}{\StopHere}{1}{
+ \read \myreada line #1 to \scratchstring #1 : \scratchstring \par
+ }
+ \immediate\closein\myreada
+\endgroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Here, instead of hard coded line numbers we used the stored values. The
+optional \type {line} keyword is a \LMTX\ speciality.
+
+\startlines \getbuffer \stoplines
+
+Actually an application can be found in a small (demonstration) module:
+
+\startbuffer
+\usemodule[system-readers]
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+This provides the code for doing this:
+
+\starttyping[option=TEX]
+\startmarkedlines[test]
+SOME LINE 1
+SOME LINE 2
+SOME LINE 3
+\stopmarkedlines
+
+\begingroup
+ \newlocalread\myreada
+ \immediate\openin\myreada {\markedfilename{test}}
+ \dostepwiserecurse{\lastmarkedline{test}}{\firstmarkedline{test}}{-1}{
+ \readline\myreada line #1 to \scratchstring #1 : \scratchstring \par
+ }
+ \immediate\closein\myreada
+\endgroup
+\stoptyping
+
+As you see in these examples, we an locally define a read channel without
+getting a message about it already being defined.
+
+\stopsection
+
+\stopdocument
+
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-security.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-security.tex
new file mode 100644
index 00000000000..4f705e37caa
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-security.tex
@@ -0,0 +1,254 @@
+% language=us
+
+% It took some time to get the right balance of using the overload related features
+% but at some point it started feeling right. Of course it will never be as
+% perfectly timed and integrated as Gavin Harrison performance on "Threatening War"
+% (youtube movie) but that doesn't mean I should not aim for perfection. But as
+% with drumming, it takes practising and that is what I did on a subset of sources
+% when writing the engine code.
+%
+% It tooks a few weeks but November 21 2020 the last of the core files was turned
+% \LMTX, not that the work was done (checking to be done (thanks Wolfgang!), imp
+% files to be checked, many \LUA\ files to be updated) but it's a start. This time
+% the musical timestamp is listening to Nikola Cvetkovic (piano) and history
+% podcasts.
+
+\usemodule[system-tokens]
+
+\environment lowlevel-style
+
+\startdocument
+ [title=security,
+ color=middleorange]
+
+\startsection[title=Preamble]
+
+Here I will discuss a moderate security subsystem of \LUAMETATEX\ and therefore
+\CONTEXT\ \LMTX. This is not about security in the sense of the typesetting
+machinery doing harm to your environment, but more about making sure that a user
+doesn't change the behavior of the macro package in ways that introduce
+interference and thereby unwanted side effect. It's all about protecting macros.
+
+This is all very experimental and we need to adapt the \CONTEXT\ source code to
+this. Actually that will happen a few times because experiments trigger that. It
+might take a few years before the security model is finalized and all files are
+updated accordingly. There are lots of files and macros involved. In the process
+the underlying features in the engine might evolve.
+
+\stopsection
+
+\startsection[title=Flags]
+
+Before we go into the security levels we see what flags can be set. The \TEX\
+language has a couple of so called prefixes that can be used when setting values
+and defining macros. Any engine that has traditional \TEX\ with \ETEX\ extensions
+can do this:
+
+\starttyping[option=TEX]
+ \def\foo{foo}
+\global \def\foo{foo}
+\global\protected\def\foo{foo}
+\stoptyping
+
+And \LUAMETATEX\ adds another one:
+
+\starttyping[option=TEX]
+ \tolerant \def\foo{foo}
+\global\tolerant \def\foo{foo}
+\global\tolerant\protected\def\foo{foo}
+\stoptyping
+
+What these prefixes do is discussed elsewhere. For now is is enough to know that
+the two optional prefixes \type {\protected} and \type {\tolerant} make for four
+distinctive cases of macro calls.
+
+But there are more prefixes:
+
+\starttabulate
+\HL
+\NC \type {frozen} \NC a macro that has to be redefined in a managed way \NC \NR
+\NC \type {permanent} \NC a macro that had better not be redefined \NC \NR
+\NC \type {primitive} \NC a primitive that normally will not be adapted \NC \NR
+\NC \type {immutable} \NC a macro or quantity that cannot be changed, it is a constant \NC \NR
+\NC \type {mutable} \NC a macro that can be changed no matter how well protected it is \NC \NR
+\HL
+\NC \type {instance} \NC a macro marked as (for instance) be generated by an interface \NC \NR
+\HL
+\NC \type {noaligned} \NC the macro becomes acceptable as \type {\noalign} alias \NC \NR
+\HL
+\NC \type {overloaded} \NC when permitted the flags will be adapted \NC \NR
+\NC \type {enforced} \NC all is permitted (but only in zero mode or ini mode) \NC \NR
+\NC \type {aliased} \NC the macro gets the same flags as the original \NC \NR
+\HL
+\stoptabulate
+
+These prefixed set flags to the command at hand which can be a macro but
+basically any control sequence.
+
+To what extent the engine will complain when a property is changed in a way that
+violates the above depends on the parameter \type {\overloadmode}. When this
+parameter is set to zero no checking takes place. More interesting are values
+larger than zero. If that is the case, when a control sequence is flagged as
+mutable, it is always permitted to change. When it is set to immutable one can
+never change it. The other flags determine the kind of checking done. Currently
+the following overload values are used:
+
+\starttabulate[|l|l|c|c|c|c|c|]
+ \NC \NC \BC immutable \BC permanent \BC primitive \BC frozen \BC instance \NC \NR
+ \NC 1 \NC warning \NC \star \NC \star \NC \star \NC \NC \NC \NR
+ \NC 2 \NC error \NC \star \NC \star \NC \star \NC \NC \NC \NR
+ \NC 3 \NC warning \NC \star \NC \star \NC \star \NC \star \NC \NC \NR
+ \NC 4 \NC error \NC \star \NC \star \NC \star \NC \star \NC \NC \NR
+ \NC 5 \NC warning \NC \star \NC \star \NC \star \NC \star \NC \star \NC \NR
+ \NC 6 \NC error \NC \star \NC \star \NC \star \NC \star \NC \star \NC \NR
+\stoptabulate
+
+The even values (except zero) will abort the run. In \CONTEXT\ we plug in a
+callback that deals with the messages. A value of 255 will freeze this parameter.
+At level five and above the \type {instance} flag is also checked but no drastic
+action takes place. We use this to signal to the user that a specific instance is
+redefined (of course the definition macros can check for that too).
+
+So, how does it work. The following is okay:
+
+\starttyping[option=TEX]
+\def\MacroA{A}
+\def\MacroB{B}
+\let\MyMacro\MacroA
+\let\MyMacro\MacroB
+\stoptyping
+
+The first two macros are ordinary ones, and the last two lines just create an alias. Such
+an alias shares the definition, but when for instance \type {\MacroA} is redefined, its
+new meaning will not be reflected in the alias.
+
+\starttyping[option=TEX]
+\permanent\protected\def\MacroA{A}
+\permanent\protected\def\MacroB{B}
+\let\MyMacro\MacroA
+\let\MyMacro\MacroB
+\stoptyping
+
+This also works, because the \type {\let} will create an alias with the protected
+property but it will not take the \type {permanent} propery along. For that we need
+to say:
+
+\starttyping[option=TEX]
+\permanent\protected\def\MacroA{A}
+\permanent\protected\def\MacroB{B}
+\permanent\let\MyMacro\MacroA
+\permanent\let\MyMacro\MacroB
+\stoptyping
+
+or, when we want to copy all properties:
+
+\starttyping[option=TEX]
+\permanent\protected\def\MacroA{A}
+\permanent\protected\def\MacroB{B}
+\aliased\let\MyMacro\MacroA
+\aliased\let\MyMacro\MacroB
+\stoptyping
+
+However, in \CONTEXT\ we have commands that we like to protect against
+overloading but at the same time have a different meaning depending on the use
+case. An example is the \type {\NC} (next column) command that has a different
+implementation in each of the table mechanisms.
+
+\starttyping[option=TEX]
+\permanent\protected\def\NC_in_table {...}
+\permanent\protected\def\NC_in_tabulate{...}
+\aliased\let\NC\NC_in_table
+\aliased\let\NC\NC_in_tabulate
+\stoptyping
+
+Here the second aliasing of \type {\NC} fails (assuming of course that we enabled
+overload checking). One can argue that grouping can be used but often no grouping
+takes place when we redefine on the fly. Because \type {frozen} is less restrictive
+than \type {primitive} or \type {permanent}, and of course \type {immutable}, the
+next variant works:
+
+\starttyping[option=TEX]
+\frozen\protected\def\NC_in_table {...}
+\frozen\protected\def\NC_in_tabulate{...}
+\overloaded\let\NC\NC_in_table
+\overloaded\let\NC\NC_in_tabulate
+\stoptyping
+
+However, in practice, as we want to keep the overload checking, we have to do:
+
+\starttyping[option=TEX]
+\frozen\protected\def\NC_in_table {...}
+\frozen\protected\def\NC_in_tabulate{...}
+\overloaded\frozen\let\NC\NC_in_table
+\overloaded\frozen\let\NC\NC_in_tabulate
+\stoptyping
+
+or use \type {\aliased}, but there might be conflicting permissions. This is not
+that nice, so there is a kind of dirty trick possible. Consider this:
+
+\starttyping[option=TEX]
+\frozen\protected\def\NC_in_table {...}
+\frozen\protected\def\NC_in_tabulate{...}
+\def\setNCintable {\enforced\let\frozen\let\NC\NC_in_table}
+\def\setNCintabulate{\enforced\let\frozen\let\NC\NC_in_tabulate}
+\stoptyping
+
+When we're in so called \type {initex} mode or when the overload mode is zero,
+the \type {\enforced} prefix is internalized in a way that signals that the
+follow up is not limited by the overload mode and permissions. This definition
+time binding mechanism makes it possible to use \type {permanent} macros that
+users cannot redefine, but existing macros can, unless of course they tweak the
+mode parameter.
+
+Now keep in mind that users can always cheat but that is intentional. If you
+really want to avoid that you can set the overload mode to 255 after which it
+cannot be set any more. However, it can be useful to set the mode to zero (or
+some warning level) when foreign macro packages are used.
+
+\stopsection
+
+\startsection[title=Complications]
+
+One side effect of all this is that all those prefixes can lead to more code. On
+the other hand we save some due to the extended macro argument handling features.
+When you take the size of the format file as reference, in the end we get a
+somewhat smaller file. Every token that you add of remove gives a 8~bytes
+difference. The extra overhead that got added to the engine is compensated by the
+fact that some macro implementations can be more efficient. In the end, in spite
+of these new features and the more extensive testing of flags performance is
+about the same. \footnote {And if you wonder about memory, by compacting the used
+(often scattered) token memory before dumping I manages to save some 512K on the
+format file, so often the loss and gain are somewhere else.}
+
+\stopsection
+
+\startsection[title=Introspection]
+
+In case you want to get some details about the properties of a macro, you can
+check its meaning. The full variant shows all of them.
+
+\startbuffer
+% a macro with two optional arguments with optional spacing in between:
+
+\permanent\tolerant\protected\def\MyFoo[#1]#*[#2]{(#1)(#2)}
+
+\meaningless\MyFoo\par
+\meaning \MyFoo\par
+\meaningfull\MyFoo\par
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startpacked \getbuffer \stoppacked
+
+\stopsection
+
+% In \CONTEXT:
+% c! v! s! ??
+% newif newcount ... newconditional etc
+% userinterface (permanent)
+% primitives
+% noaligned
+% frozen is for users
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lua/lua-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lua/lua-mkiv.tex
index 25a3d178661..61d7dddad3c 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/lua/lua-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lua/lua-mkiv.tex
@@ -65,8 +65,8 @@
fill Page withcolor \MPcolor{maincolor} ;
- draw textext.urt("\TitlePageFont \getvariable{document}{title}") xsized (0.8w) shifted (.1w,.2h) withcolor .80white ;
- draw textext.top("\TitlePageFont \getvariable{document}{subtitle}") xsized (0.8w) shifted (.5w,.1h) withcolor .60white ;
+ draw textext.urt("\TitlePageFont \documentvariable{title}") xsized (0.8w) shifted (.1w,.2h) withcolor .80white ;
+ draw textext.top("\TitlePageFont \documentvariable{subtitle}") xsized (0.8w) shifted (.5w,.1h) withcolor .60white ;
StopPage ;
@@ -132,9 +132,9 @@ where it can find them.
\startsubject[title={Colofon}]
\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC author \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC website \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\NC copyright \NC \symbol[cc][cc-by-sa-nc] \NC \NR
\stoptabulate
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-arrow.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-arrow.tex
index 72c9528e8b3..a2c4636ed36 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-arrow.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-arrow.tex
@@ -34,10 +34,10 @@ draw lmt_arrow [
\startbuffer[1c]
\startMPcode
draw lmt_arrow [
- path = (fullcircle scaled 3cm rotated 45),
- pen = (pencircle xscaled 2mm yscaled 1mm rotated 45),
+ path = (fullcircle scaled 3cm rotated 145),
+ pen = (pencircle xscaled 4mm yscaled 2mm rotated 45),
]
- withpen pencircle xscaled 2mm yscaled 1mm rotated 45
+ withpen pencircle xscaled 1mm yscaled .5mm rotated 45
withcolor "darkblue" ;
\stopMPcode
\stopbuffer
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-color.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-color.tex
new file mode 100644
index 00000000000..17f4a449d36
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-color.tex
@@ -0,0 +1,138 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-color
+
+\startchapter[title={Color}]
+
+There are by now plenty of examples made by users that use color and \METAFUN\
+provides all kind of helpers. So do we need more? When I play around with things
+or when users come with questions that then result in a nice looking graphic, the
+result might en dup as example of coding. The following is an example of showing
+of colors. We have a helper that goes from a so called lab specification to rgb
+and it does that via xyz transformations. It makes no real sense to interface
+this beyond this converter. We use this opportunity to demonstrate how to make
+an interface.
+
+\startbuffer
+\startMPdefinitions
+ vardef cielabmatrix(expr l, mina, maxa, minb, maxb, stp) =
+ image (
+ for a = mina step stp until maxa :
+ for b = minb step stp until maxb :
+ draw (a,b) withcolor labtorgb(l,a,b) ;
+ endfor ;
+ endfor ;
+ )
+ enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\getbuffer
+
+Here we define a macro that makes a color matrix. It can be used as follows
+
+\startbuffer
+\startcombination[nx=4,ny=1]
+ {\startMPcode draw cielabmatrix(20, -100, 100, -100, 100, 5) ysized 35mm withpen pencircle scaled 2.5 ; \stopMPcode} {\type {l = 20}}
+ {\startMPcode draw cielabmatrix(40, -100, 100, -100, 100, 5) ysized 35mm withpen pencircle scaled 2.5 ; \stopMPcode} {\type {l = 40}}
+ {\startMPcode draw cielabmatrix(60, -100, 100, -100, 100, 5) ysized 35mm withpen pencircle scaled 2.5 ; \stopMPcode} {\type {l = 60}}
+ {\startMPcode draw cielabmatrix(80, -100, 100, -100, 100, 5) ysized 35mm withpen pencircle scaled 2.5 ; \stopMPcode} {\type {l = 80}}
+\stopcombination
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+One can of course mess around a bit:
+
+\startbuffer
+\startcombination[nx=4,ny=1]
+ {\startMPcode draw cielabmatrix(20, -100, 100, -100, 100, 10) ysized 35mm randomized 1 withpen pensquare scaled 4 ; \stopMPcode} {\type {l = 20}}
+ {\startMPcode draw cielabmatrix(40, -100, 100, -100, 100, 10) ysized 35mm randomized 1 withpen pensquare scaled 4 ; \stopMPcode} {\type {l = 40}}
+ {\startMPcode draw cielabmatrix(60, -100, 100, -100, 100, 10) ysized 35mm randomized 1 withpen pensquare scaled 4 ; \stopMPcode} {\type {l = 60}}
+ {\startMPcode draw cielabmatrix(80, -100, 100, -100, 100, 10) ysized 35mm randomized 1 withpen pensquare scaled 4 ; \stopMPcode} {\type {l = 80}}
+\stopcombination
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Normally, when you don't go beyond this kind of usage, a simple macro like the
+above will do. But when you want to make something that is upward compatible
+(which is one of the principles behind the \CONTEXT\ user interface(s), you can
+do this:
+
+\startbuffer
+\startcombination[nx=4,ny=1]
+ {\startMPcode draw lmt_labtorgb [ l = 20, step = 20 ] ysized 35mm withpen pencircle scaled 8 ; \stopMPcode} {\type {l = 20}}
+ {\startMPcode draw lmt_labtorgb [ l = 40, step = 20 ] ysized 35mm withpen pencircle scaled 8 ; \stopMPcode} {\type {l = 40}}
+ {\startMPcode draw lmt_labtorgb [ l = 60, step = 20 ] ysized 35mm withpen pencircle scaled 8 ; \stopMPcode} {\type {l = 60}}
+ {\startMPcode draw lmt_labtorgb [ l = 80, step = 20 ] ysized 35mm withpen pencircle scaled 8 ; \stopMPcode} {\type {l = 80}}
+\stopcombination
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+This is a predefined macro in the reserved \type {lmt_} namespace (don't use that
+one yourself, create your own). First we preset the possible parameters:
+
+\starttyping[option=MP]
+presetparameters "labtorgb" [
+ mina = -100,
+ maxa = 100,
+ minb = -100,
+ maxb = 100,
+ step = 5,
+ l = 50,
+] ;
+\stoptyping
+
+Next we define the main interface macro:
+
+\starttyping[option=MP]
+def lmt_labtorgb = applyparameters "labtorgb" "lmt_do_labtorgb" enddef ;
+\stoptyping
+
+Last we do the actual implementation, which looks a lot like the one we
+started with:
+
+\starttyping[option=MP]
+vardef lmt_do_labtorgb =
+ image (
+ pushparameters "labtorgb" ;
+ save l ; l := getparameter "l" ;
+ for a = getparameter "mina" step getparameter "step"
+ until getparameter "maxa" :
+ for b = getparameter "minb" step getparameter "step"
+ until getparameter "maxb" :
+ draw (a,b) withcolor labtorgb(l,a,b) ;
+ endfor ;
+ endfor ;
+ popparameters ;
+ )
+enddef ;
+\stoptyping
+
+Of course we can now add all kind of extra features but this is what we currently
+have. Maybe this doesn't belong in the \METAFUN\ core but it's not that much code
+and a nice demo. After all, there is much in there that is seldom used.
+
+\stopchapter
+
+\stopcomponent
+
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-introduction.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-introduction.tex
index 6892b21ce84..fa0e28510b1 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-introduction.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-introduction.tex
@@ -76,7 +76,7 @@ have a collection of modules for specific tasks.
\startlines
Hans Hagen
Hasselt NL
-August 2019 (and beyond)
+August 2021 (and beyond)
\stoplines
\stopchapter
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-poisson.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-poisson.tex
new file mode 100644
index 00000000000..cd4b6ddabd8
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-poisson.tex
@@ -0,0 +1,159 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-poisson
+
+\startchapter[title={Poisson}]
+
+
+When, after a post on the \CONTEXT\ mailing list, Aditya pointed me to an article
+on mazes I ended up at poisson distributions which to me looks nicer than what I
+normally do, fill a grid and then randomize the resulting positions. With some
+hooks this can be used for interesting patterns too. The algorithm is based on
+the discussion at:
+
+\starttyping
+http://devmag.org.za/2009/05/03/poisson-disk-sampling
+\stoptyping
+
+Other websites mention some variants on that but I saw no reason to look into
+those in detail. I can imagine more random related variants in this domain so
+consider this an appetizer. The user is rather simple because some macro is
+assumed to deal with the rendering of the distributed points. We just show some
+examples (because the interface might evolve).
+
+\startbuffer
+\startMPcode
+ draw lmt_poisson [
+ width = 40,
+ height = 40,
+ distance = 1,
+ count = 20,
+ macro = "draw"
+ ] xsized 4cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+\startbuffer
+\startMPcode
+ vardef tst (expr x, y, i, n) =
+ fill fullcircle scaled (10+10*(i/n)) shifted (10x,10y)
+ withcolor "darkblue" withtransparency (1,.5) ;
+ enddef ;
+
+ draw lmt_poisson [
+ width = 50,
+ height = 50,
+ distance = 1,
+ count = 20,
+ macro = "tst",
+ arguments = 4
+ ] xsized 6cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+\startbuffer
+\startMPcode
+ vardef tst (expr x, y, i, n) =
+ fill fulldiamond scaled (5+5*(i/n)) randomized 2 shifted (10x,10y)
+ withcolor "darkgreen" ;
+ enddef ;
+
+ draw lmt_poisson [
+ width = 50,
+ height = 50,
+ distance = 1,
+ count = 20,
+ macro = "tst",
+ initialx = 10,
+ initialy = 10,
+ arguments = 4
+ ] xsized 6cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+\startbuffer
+\startMPcode{doublefun}
+ vardef tst (expr x, y, i, n) =
+ fill fulldiamond randomized (.2*i/n) shifted (x,y);
+ enddef ;
+
+ draw lmt_poisson [
+ width = 150,
+ height = 150,
+ distance = 1,
+ count = 20,
+ macro = "tst",
+ arguments = 4
+ ] xsized 6cm withcolor "darkmagenta" ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+\startbuffer
+\startMPcode
+ vardef tst (expr x, y, i, n) =
+ draw externalfigure "cow.pdf" ysized (10+5*i/n) shifted (10x,10y);
+ enddef ;
+ draw lmt_poisson [
+ width = 20,
+ height = 20,
+ distance = 1,
+ count = 20,
+ macro = "tst"
+ arguments = 4,
+ ] xsized 6cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
+The supported parameters are:
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC width \NC numeric \NC 50 \NC \NC \NR
+\NC height \NC numeric \NC 50 \NC \NC \NR
+\NC distance \NC numeric \NC 1 \NC \NC \NR
+\NC count \NC numeric \NC 20 \NC \NC \NR
+\NC macro \NC string \NC "draw" \NC \NC \NR
+\NC initialx \NC numeric \NC 10 \NC \NC \NR
+\NC initialy \NC numeric \NC 10 \NC \NC \NR
+\NC arguments \NC numeric \NC 4 \NC \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-technology.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-technology.tex
new file mode 100644
index 00000000000..910a9dd6034
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun-technology.tex
@@ -0,0 +1,89 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-technology
+
+\startchapter[title={Technology}]
+
+The \METAPOST\ library that we use in \LUAMETATEX\ is a follow up on the library
+used in \LUATEX\ which itself is a follow up on the original \METAPOST\ program
+that again was a follow up on Don Knuths \METAFONT, the natural companion to
+\TEX.
+
+When we start with John Hobbies \METAPOST\ we see a graphical engine that
+provides a simple but powerful programming language meant for making graphics,
+not the freehand kind, but the more systematic ones. The output is \POSTSCRIPT\
+but a simple kind that can easily be converted to \PDF. \footnote {For that
+purpose I wrote a converter in the \TEX\ language for \PDFTEX, and even within
+the limitations of \TEX\ at that time (fonts, number of registers, memory) it
+worked out quite well.} It's output is very accurate and performance is great.
+
+As part of the \LUATEX\ development project Taco Hoekwater turned \METAPOST\ into
+\MPLIB, a downward compatible library where \METAPOST\ became a small program
+using that library. But there is more: there are (when enabled) backends that
+produce \PNG\ or \SVG, but when used these also add dependencies on moving
+targets. The library by default uses the so called scaled numbers: floats that
+internally are long integers. But it can also work in doubles, decimal and binary
+and especially the last two create a dependency on libraries. It is good to
+notice that as in the original \METAPOST\ the \POSTSCRIPT\ output handling is
+visible all over the source. Also, the way \TYPEONE\ fonts are handled has been
+extended, for instance by providing access to shapes.
+
+At some point a \LUA\ interface got added that made it possible to call out to
+the \LUA\ instance used in \LUATEX, so the three concepts: \TEX, \METAPOST\ and
+\LUA\ can combine forces. A snippet of code can be run, and a result can be piped
+back. Although there is some limited access to \METAPOST\ internals, the normal
+way to go is by serializing \METAPOST\ data to the \LUA\ end and let \METAPOST\
+scan the result using \type {scantokens}.
+
+The library in \LUAMETATEX\ is a bit different. Of course it has the same core
+graphic engine, but there is no longer a backend. In \CONTEXT\ \MKIV\ the
+\POSTSCRIPT\ (and other) backends were not used anyway because it operates on the
+exported \LUA\ representation of the result. Combined with the \type {prescript}
+and \type {postscript} features introduced in the library that provides all we
+need to make interesting extensions to the graphical engine (color, shading,
+image inclusion, text, etc). The \METAPOST\ font support features are also not
+used because we need support for \OPENTYPE\ and even in \MKII\ (for \PDFTEX\ and
+\XETEX) we used a different approach to fonts.
+
+It is for that reason that the library we use in \LUAMETATEX\ is a leaner version
+of its ancestor. As mentioned, there is no backend code, only the \LUA\ export,
+which saves a lot, and there are no traces of font support left, which also drops
+many lines of code. We forget about the binary number model because it needs a
+large library that also occasionally changes, but one can add it if needed. This
+means that there are no dependencies except for decimal but that library is
+relatively small and doesn't change at all. It also means that the resulting
+\MPLIB\ library is much smaller, but it's still a substantial component in
+\LUAMETATEX. Internally I use the future version number 3. The original
+\METAPOST\ program is version 1, so the library got version 2, and that one
+basically being frozen (it's in bug|-|fix mode) means that it will stick to that.
+
+Another difference is that from the \LUA\ end one has access to several scanners
+and also has possibilities to efficiently push back results to the engine.
+Running scripts can also be done more efficient. This permits a rather efficient
+(in terms of performance and memory usage) way to extend the language and add for
+instance key|/|value based interfaces. There are some more additions, like for
+instance pre- and postscripts to clip, boundary and group objects. Internals can
+be numeric, string and boolean. One can use \UTF\ input although that has also be
+added to the ancestor. Some redundant internal input|/|output remapping has been
+removed and we are more tolerant to newlines in return values from \LUA. Error
+messages have been normalized, internal documentation cleaned up a bit. A few
+anomalies have been fixed too. All in- and output is now under \LUA\ control.
+Etcetera. The (now very few) source files are still \CWEB\ files but the
+conversion to \CCODE\ is done with a \LUA\ script that uses (surprise) the
+\LUAMETATEX\ engine as \LUA\ processor. This give a bit nicer \CCODE\ output for
+when we view it in e.g.\ Visual Studio too (normally the \CWEB\ output is not
+meant to be seen by humans).
+
+Keep in mind that it's still \METAPOST\ with all it provided, but some has to be
+implemented in macros or in \LUA\ via callbacks. The simple fact that the
+original library is the standard and is also the core of \METAPOST\ most of these
+changes and additions cannot be backported to the original, but that is no big
+deal. The advantage is that we can experiment with new features without
+endangering users outside the \CONTEXT\ bubble. The same is true for the \LUA\
+interface, which already is upgraded in many aspects.
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun.tex
index 2dd917cdfcf..6aaf166a5ed 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametafun/luametafun.tex
@@ -1,3 +1,6 @@
+% This file takes a while to process because we render some complex graphics. It
+% can be sped up by enabling caching, but for some images that has been disabled.
+
\setupfootertexts[{\tttf uncorrected draft}]
\environment luametafun-style
@@ -12,6 +15,7 @@
\stopfrontmatter
\startbodymatter
+ \component luametafun-technology
\component luametafun-text
% \component luametafun-grid
\component luametafun-axis
@@ -26,7 +30,9 @@
\component luametafun-function
\component luametafun-chart
\component luametafun-svg
+ \component luametafun-poisson
\component luametafun-fonts
+ \component luametafun-color
\component luametafun-groups
\component luametafun-interface
\stopbodymatter
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex
index 244c06c2a5c..d8e98efa291 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex
@@ -15,6 +15,9 @@
\libindex{find}
\libindex{known}
+{\em The callbacks are a moving target. Don't bother me with questions about
+them.}
+
This library has functions that register, find and list callbacks. Callbacks are
\LUA\ functions that are called in well defined places. There are two kinds of
callbacks: those that mix with existing functionality, and those that (when
@@ -73,147 +76,56 @@ if callback.known("foo") then ... end
\startsection[title={File related callbacks}][library=callback]
-The behaviour documented in this subsection is considered stable in the sense that
-there will not be backward|-|incompatible changes any more.
-
-\subsection{\cbk {find_read_file}}
-
-Your callback function should have the following conventions:
-
-\startfunctioncall
-<string> actual_name =
- function (<number> id_number, <string> asked_name)
-\stopfunctioncall
-
-Arguments:
-
-\startitemize
-
-\sym{id_number}
-
-This number is zero for the log or \prm {input} files. For \TEX's \prm {read}
-or \prm {write} the number is incremented by one, so \type {\read0} becomes~1.
-
-\sym{asked_name}
-
-This is the user|-|supplied filename, as found by \prm {input}, \prm {openin}
-or \prm {openout}.
-
-\stopitemize
-
-Return value:
-
-\startitemize
-
-\sym{actual_name}
-
-This is the filename used. For the very first file that is read in by \TEX, you
-have to make sure you return an \type {actual_name} that has an extension and
-that is suitable for use as \type {jobname}. If you don't, you will have to
-manually fix the name of the log file and output file after \LUATEX\ is finished,
-and an eventual format filename will become mangled. That is because these file
-names depend on the jobname.
-
-You have to return \type {nil} if the file cannot be found.
-
-\stopitemize
-
-\subsection{\cbk {find_data_file}}
-
-\topicindex{callbacks+data files}
-
-Your callback function should have the following conventions:
-
-\startfunctioncall
-<string> actual_name =
- function (<string> asked_name)
-\stopfunctioncall
-
-Return \type {nil} if the file cannot be found.
-
-\subsection{\cbk {find_format_file}}
+\subsection{\cbk {find_format_file} and \cbk {find_log_file}}
\topicindex{callbacks+format file}
+\topicindex{callbacks+log file}
-Your callback function should have the following conventions:
+These callbacks are called as:
\startfunctioncall
-<string> actual_name =
- function (<string> asked_name)
+<string> actualname =
+ function (<string> askedname)
\stopfunctioncall
-The \type {asked_name} is a format file for reading (the format file for writing
-is always opened in the current directory).
+The \type {askedname} is a format file for reading (the format file for writing
+is always opened in the current directory) or a log file for writing.
-\subsection{\cbk {open_read_file}}
+\subsection{\cbk {open_data_file}}
\topicindex{callbacks+opening files}
-Your callback function should have the following conventions:
+This callback function gets a filename passed:
\startfunctioncall
-<table> env =
- function (<string> file_name)
+<table> env = function (<string> filename)
\stopfunctioncall
-Argument:
-
-\startitemize
-
-\sym{file_name}
-
-The filename returned by a previous \cbk {find_read_file} or the return value of
-\type {kpse.find_file()} if there was no such callback defined.
-
-\stopitemize
-
-Return value:
-
-\startitemize
-
-\sym{env}
-
-This is a table containing at least one required and one optional callback
-function for this file. The required field is \type {reader} and the associated
-function will be called once for each new line to be read, the optional one is
-\type {close} that will be called once when \LUATEX\ is done with the file.
+The return value is either the boolean value false or a table with two functions.
+A mandate \type {reader} function fill be called once for each new line to be
+read, the optional \type {close} function will be called once \LUATEX\ is done
+with the file.
\LUATEX\ never looks at the rest of the table, so you can use it to store your
private per|-|file data. Both the callback functions will receive the table as
their only argument.
-\stopitemize
-
-\subsubsection{\type {reader}}
-
-\topicindex{callbacks+reader}
-
-\LUATEX\ will run this function whenever it needs a new input line from the file.
-
-\startfunctioncall
-function(<table> env)
- return <string> line
-end
-\stopfunctioncall
-
-Your function should return either a string or \type {nil}. The value \type {nil}
-signals that the end of file has occurred, and will make \TEX\ call the optional
-\type {close} function next.
-
-\subsubsection{\type {close}}
-
-\topicindex{callbacks+closing files}
-
-\LUATEX\ will run this optional function when it decides to close the file.
-
-\startfunctioncall
-function(<table> env)
-end
-\stopfunctioncall
-
-Your function should not return any value.
-
-\stopsection
+% No longer needed anyway.
+%
+% \subsection{\cbk {if_end_of_file}}
+%
+% \topicindex{callbacks+checking files}
+%
+% This callback has no arguments and your function should return true or false. The
+% callback is triggered by \type {\ifeof}. It's up to the macro package to come up
+% with a reasonable implementation. By default the test is always true.
+%
+% \startfunctioncall
+% <boolean> eof =
+% function ()
+% \stopfunctioncall
+%
+% \stopsection
\startsection[title={Data processing callbacks}][library=callback]
@@ -339,7 +251,7 @@ into a stack of \prm {hbox}es, after the addition of \prm {parfillskip}.
\startfunctioncall
function(<node> head, <string> groupcode)
- return true | false | <node> newhead
+ return <node> newhead
end
\stopfunctioncall
@@ -441,7 +353,7 @@ stack of \prm {hbox}es.
\startfunctioncall
function(<node> head, <string> groupcode)
- return true | false | <node> newhead
+ return <node> newhead
end
\stopfunctioncall
@@ -457,7 +369,7 @@ material. Math items and line boxes are ignored at the moment.
\startfunctioncall
function(<node> head, <string> groupcode, <number> size,
<string> packtype [, <string> direction] [, <node> attributelist])
- return true | false | <node> newhead
+ return <node> newhead
end
\stopfunctioncall
@@ -485,7 +397,7 @@ that it is called at different moments, there is an extra variable that matches
\startfunctioncall
function(<node> head, <string> groupcode, <number> size, <string> packtype,
<number> maxdepth [, <string> direction] [, <node> attributelist]))
- return true | false | <node> newhead
+ return <node> newhead
end
\stopfunctioncall
@@ -550,7 +462,7 @@ This callback is called when \TEX\ is ready to start boxing the box 255 for \prm
\startfunctioncall
function(<node> head, <string> groupcode, <number> size, <string> packtype,
<number> maxdepth [, <string> direction])
- return true | false | <node> newhead
+ return <node> newhead
end
\stopfunctioncall
@@ -619,13 +531,13 @@ pass.
You must not ruin the node list. For instance, the head normally is a local par node,
and the tail a glue. Messing too much can push \LUATEX\ into panic mode.
-\subsection{\type {insert_local_par}}
+\subsection{\type {insert_par}}
Each paragraph starts with a local par node that keeps track of for instance
the direction. You can hook a callback into the creator:
\startfunctioncall
-function(<node> local_par, <string> location)
+function(<node> par, <string> location)
end
\stopfunctioncall
@@ -694,7 +606,7 @@ This callback replaces the code that prints \LUATEX's statistics and \quote
{output written to} messages. The engine can still do housekeeping and therefore
you should not rely on this hook for postprocessing the \PDF\ or log file.
-\subsection{\cbk {show_error_hook}}
+\subsection{\cbk {intercept_tex_error}, \cbk {intercept_lua_error}}
\topicindex{callbacks+errors}
@@ -706,31 +618,22 @@ end
This callback is run from inside the \TEX\ error function, and the idea is to
allow you to do some extra reporting on top of what \TEX\ already does (none of
the normal actions are removed). You may find some of the values in the \type
-{status} table useful. This callback does not replace any internal code.
+{status} table useful. The \TEX\ related callback gets two arguments: the current
+processing mode and a boolean indicating if there was a runaway.
-\subsection{\cbk {show_error_message}}
+\subsection{\cbk {show_error_message} and \cbk {show_warning_message}}
\topicindex{callbacks+errors}
+\topicindex{callbacks+warnings}
\startfunctioncall
function()
end
\stopfunctioncall
-This callback replaces the code that prints the error message. The usual
+These callback replaces the code that prints the error message. The usual
interaction after the message is not affected.
-\subsection{\cbk {show_lua_error_hook}}
-
-\topicindex{callbacks+errors}
-
-\startfunctioncall
-function()
-end
-\stopfunctioncall
-
-This callback replaces the code that prints the extra \LUA\ error message.
-
\subsection{\cbk {start_file}}
\topicindex{callbacks+files}
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-codes.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-codes.tex
new file mode 100644
index 00000000000..103bb247310
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-codes.tex
@@ -0,0 +1,22 @@
+\environment luametatex-style
+
+\startcomponent luametatex-codes
+
+\startchapter[title=Primitive codes]
+
+here follows a list with all primitives and their category is shown. When the
+engine starts up in ini mode all primitives get defined along with some
+properties that makes it possible to do a reverse lookup of a combination of
+command code and char code. But, a primitive, being also a regular command can be
+redefined later on. The table below shows the original pairs but in \CONTEXT\
+some of these primitives are redefined. However, any macro that fits a command
+and char pair is (reported as) a primitive in logs and error messages. In the end
+all tokens are such a combination, The first 16 command codes are reserved for
+characters (the whole \UNICODE\ range can be used as char code) with specific
+catcodes and not mentioned in the list.
+
+\ctxlua{document.allprimitives()}
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
index 35812b13fcf..5be5463e97e 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
@@ -10,7 +10,7 @@ As \LUAMETATEX\ is a leaner and meaner \LUATEX, this chapter will discuss
what is gone. We start with the primitives that were dropped.
\starttabulate[|l|pl|]
-\NC fonts \NC \type {\letterspacefont}
+\BC fonts \NC \type {\letterspacefont}
\type {\copyfont}
\type {\expandglyphsinfont}
\type {\ignoreligaturesinfont}
@@ -18,7 +18,7 @@ what is gone. We start with the primitives that were dropped.
\type {\leftghost}
\type {\rightghost}
\NC \NR
-\NC backend \NC \type {\dviextension}
+\BC backend \NC \type {\dviextension}
\type {\dvivariable }
\type {\dvifeedback}
\type {\pdfextension}
@@ -28,14 +28,14 @@ what is gone. We start with the primitives that were dropped.
\type {\draftmode}
\type {\outputmode}
\NC \NR
-\NC dimensions \NC \type {\pageleftoffset}
+\BC dimensions \NC \type {\pageleftoffset}
\type {\pagerightoffset}
\type {\pagetopoffset}
\type {\pagebottomoffset}
\type {\pageheight}
\type {\pagewidth}
\NC \NR
-\NC resources \NC \type {\saveboxresource}
+\BC resources \NC \type {\saveboxresource}
\type {\useboxresource}
\type {\lastsavedboxresourceindex}
\type {\saveimageresource}
@@ -43,11 +43,11 @@ what is gone. We start with the primitives that were dropped.
\type {\lastsavedimageresourceindex}
\type {\lastsavedimageresourcepages}
\NC \NR
-\NC positioning \NC \type {\savepos}
+\BC positioning \NC \type {\savepos}
\type {\lastxpos}
\type {\lastypos}
\NC \NR
-\NC directions \NC \type {\textdir}
+\BC directions \NC \type {\textdir}
\type {\linedir}
\type {\mathdir}
\type {\pardir}
@@ -56,21 +56,25 @@ what is gone. We start with the primitives that were dropped.
\type {\pagedirection}
\type {\bodydirection}
\NC \NR
-\NC randomizer \NC \type {\randomseed}
+\BC randomizer \NC \type {\randomseed}
\type {\setrandomseed}
\type {\normaldeviate}
\type {\uniformdeviate}
\NC \NR
-\NC utilities \NC \type {\synctex}
+\BC utilities \NC \type {\synctex}
\NC \NR
-\NC extensions \NC \type {\latelua}
+\BC extensions \NC \type {\latelua}
\type {\lateluafunction}
- \type {\immediate}
\type {\openout}
\type {\write}
\type {\closeout}
+ \type {\openin}
+ \type {\read}
+ \type {\readline}
+ \type {\closein}
+ \type {\ifeof}
\NC \NR
-\NC control \NC \type {\suppressfontnotfounderror}
+\BC control \NC \type {\suppressfontnotfounderror}
\type {\suppresslongerror}
\type {\suppressprimitiveerror}
\type {\suppressmathparerror}
@@ -78,10 +82,11 @@ what is gone. We start with the primitives that were dropped.
\type {\suppressoutererror}
\type {\mathoption}
\NC \NR
-\NC whatever \NC \type {\primitive}
+\BC system \NC \type {\primitive}
\type {\ifprimitive}
+ \type {\formatname}
\NC \NR
-\NC ignored \NC \type {\long}
+\BC ignored \NC \type {\long}
\type {\outer}
\type {\mag}
\NC \NR
@@ -96,50 +101,68 @@ and they don't work well in \LUATEX\ anyway. We only have two directions left.
The primitive related extensions were not that useful and reliable so they have
been removed. There are some new variants that will be discussed later. The \type
{\outer} and \type {\long} prefixes are gone as they don't make much sense
-nowadays and them becoming dummies opened the way to something new, again to be
-discussed elsewhere. I don't think that (\CONTEXT) users will notice it. The
-\type {\suppress..} features are now default.
+nowadays and them becoming dummies opened the way to something new: control
+sequence properties that permit protection against as well as controlled
+overloading of definitions. I don't think that (\CONTEXT) users will notice these
+prefixed being gone. The definition and parsing related \type {\suppress..}
+features are now default and can't be changed so related primitives are gone.
The \type {\shipout} primitive does no ship out but just erases the content of
-the box, if that hasn't happened already in another way.
-
-The extension primitives relate to the backend (when not immediate) and can be
-implemented as part of a backend design using generic whatsits. There is only one
-type of whatsit now. In fact we're now closer to original \TEX\ with respect to
-the extensions.
+the box, if that hasn't happened already in another way. A macropackage should
+implement its own backend and related shipout. Talking of backend, the extension
+primitives that relate to backends can be implemented as part of a backend design
+using generic whatsits. There is only one type of whatsit now. In fact we're now
+closer to original \TEX\ with respect to the extensions.
The \type {img} library has been removed as it's rather bound to the backend. The
\type {slunicode} library is also gone. There are some helpers in the string
library that can be used instead and one can write additional \LUA\ code if
-needed. There is no longer a \type {pdf} backend library.
+needed. There is no longer a \type {pdf} backend library but we have an up to
+date \PDF\ parsing library on board.
In the \type {node}, \type {tex} and \type {status} library we no longer have
helpers and variables that relate to the backend. The \LUAMETATEX\ engine is in
-principle \DVI\ and \PDF\ unaware. There are only generic whatsit nodes that can
-be used for some management related tasks. For instance you can use them to
-implement user nodes.
+principle \DVI\ and \PDF\ unaware. There are, as mentioned, only generic whatsit
+nodes that can be used for some management related tasks. For instance you can
+use them to implement user nodes. More extensive status information is provided
+in the overhauled status library.
The margin kern nodes are gone and we now use regular kern nodes for them. As a
consequence there are two extra subtypes indicating the injected left or right
kern. The glyph field served no real purpose so there was no reason for a special
kind of node.
-The \KPSE\ library is no longer built|-|in. Because there is no backend, quite
-some file related callbacks could go away. The following file related callbacks
+The \KPSE\ library is no longer built|-|in, but one can use an external \KPSE\
+library, assuming that it is present on the system, because the engine has a so
+called optional library interface to it. Because there is no backend, quite some
+file related callbacks could go away. The following file related callbacks
remained (till now):
\starttyping
-find_write_file find_data_file find_format_file
-open_data_file read_data_file
+find_write_file find_format_file open_data_file
\stoptyping
-Also callbacks related to errors stay:
+The callbacks related to errors are changed:
\starttyping
-show_error_hook show_lua_error_hook,
+intercept_tex_error intercept_lua_error
show_error_message show_warning_message
\stoptyping
+There is a hook that gets called when one of the fundamental memory structures
+gets reallocated.
+
+\starttyping
+trace_memory
+\stoptyping
+
+When you use the overload protect mechanisms, a callback can be plugged in to handle
+exceptions:
+
+\starttyping
+handle_overload
+\stoptyping
+
The (job) management hooks are kept:
\starttyping
@@ -158,19 +181,9 @@ show_whatsit
Being the core of extensibility, the typesetting callbacks of course stayed. This
is what we ended up with:
-% \ctxlua{inspect(table.sortedkeys(callbacks.list))}
-
-\starttyping
-find_log_file, find_data_file, find_format_file, open_data_file, read_data_file,
-process_jobname, start_run, stop_run, define_font, pre_output_filter,
-buildpage_filter, hpack_filter, vpack_filter, hyphenate, ligaturing, kerning,
-pre_linebreak_filter, linebreak_filter, post_linebreak_filter,
-append_to_vlist_filter, mlist_to_hlist, pre_dump, start_file, stop_file,
-handle_error_hook, show_error_hook, show_lua_error_hook, show_error_message,
-show_warning_message, hpack_quality, vpack_quality, insert_local_par,
-contribute_filter, build_page_insert, wrapup_run, new_graf, make_extensible,
-show_whatsit, terminal_input,
-\stoptyping
+\startalign[flushleft,nothyphenated]
+\tt \cldcontext{table.concat(table.sortedkeys(callbacks.list), ", ")}
+\stopalign
As in \LUATEX\ font loading happens with the following callback. This time it
really needs to be set because there is no built|-|in font loader.
@@ -182,10 +195,10 @@ define_font
There are all kinds of subtle differences in the implementation, for instance we
no longer intercept \type {*} and \type {&} as these were already replaced long
ago in \TEX\ engines by command line options. Talking of options, only a few are
-left.
+left. All input goes via \LUA, even the console.
We took our time for reaching a stable state in \LUATEX. Among the reasons is the
-fact that most was experimented with in \CONTEXT. It took many man|-|years to
+fact that most was experimented with in \CONTEXT. It took many years of work to
decide what to keep and how to do things. Of course there are places when things
can be improved and it might happen in \LUAMETATEX. Contrary to what is sometimes
suggested, the \LUATEX|-|\CONTEXT\ \MKIV\ combination (assuming matched versions)
@@ -207,10 +220,71 @@ might be noticed that it is not possible to backtrack or inject something. Of
course it is no big deal to implement all that in \LUA\ if needed. It removes a
system dependency and makes for a bit cleaner code.
-There are new primitives too as well as some extensions to existing primitive
+There are new primitives as well as some extensions to existing primitive
functionality. These are described in following chapters but there might be
hidden treasures in the binary. If you locate them, don't automatically assume
-them to stay, some might be part of experiments!
+them to stay, some might be part of experiments! There are for instance a few
+csname related definers, we have integer and dimension constants, the macro
+argument parser can be brought in tolerant mode, the repertoire of conditionals
+has been extended, some internals can be controlled (think of normalization of
+lines, hyphenation etc.), and macros can be protected against user overload. Not
+all is discussed in detail in this manual but there are introductions in the
+\CONTEXT\ distribution that explain them. But the \TEX\ kernel is of course
+omnipresent.
+
+\startluacode
+
+local luametatex = tex.primitives()
+local luatex = table.load("luatex-primitives.lua")
+
+if not luatex then
+ local tex = "\\starttext \\ctxlua {table.save(tex.jobname .. '.lua',tex.primitives())} \\stoptext"
+
+ io.savedata("luatex-primitives.tex", tex)
+
+ os.execute("context --luatex --once luatex-primitives")
+
+ luatex = table.load("luatex-primitives.lua")
+end
+
+
+if luatex and luametatex then
+
+ luatex = table.tohash(luatex)
+ luametatex = table.tohash(luametatex)
+
+ -- context.page()
+
+ context("The following primitives are available in \\LUATEX\\ but not in \\LUAMETATEX. ")
+ context("Some of these are emulated in \\CONTEXT.")
+
+ context.startcolumns { n = 2 }
+ for k, v in table.sortedhash(luatex) do
+ if not luametatex[k] then
+ context.type(k)
+ context.crlf()
+ end
+ end
+ context.stopcolumns()
+
+
+ -- context.page()
+
+ context("The following primitives are available in \\LUAMETATEX\\ only. ")
+ context("At some point in time some might be added to \\LUATEX.")
+
+ context.startcolumns { n = 2 }
+ for k, v in table.sortedhash(luametatex) do
+ if not luatex[k] then
+ context.type(k)
+ context.crlf()
+ end
+ end
+ context.stopcolumns()
+
+end
+
+\stopluacode
\stopchapter
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
index f295b34643a..947b2320a13 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
@@ -19,7 +19,7 @@ and there will be no \type {luametatex} variants. This is because we consider
\LUAMETATEX\ to be \LUATEX 2\high{+}.
Contrary to the \LUATEX\ engine \LUAMETATEX\ enables all its primitives. You can
-clone (a selection of) primitives with a different prefix, like:
+clone (a selection of) primitives with a different prefix, like this:
\starttyping
\directlua { tex.enableprimitives('normal',tex.extraprimitives()) }
@@ -27,38 +27,26 @@ clone (a selection of) primitives with a different prefix, like:
The \type {extraprimitives} function returns the whole list or a subset,
specified by one or more keywords \type {core}, \type {tex}, \type {etex} or
-\type {luatex}. \footnote {At some point this function might be changed to return
-the whole list always}.
+\type {luatex}. When you clone all primitives you can also do this:
+
+\starttyping
+\directlua { tex.enableprimitives('normal',true) }
+\stoptyping
But be aware that the curly braces may not have the proper \prm {catcode}
assigned to them at this early time (giving a \quote {Missing number} error), so
it may be needed to put these assignments before the above line:
\starttyping
-\catcode `\{=1
-\catcode `\}=2
+\catcode `\{ = 1
+\catcode `\} = 2
\stoptyping
More fine|-|grained primitives control is possible and you can look up the
details in \in {section} [luaprimitives]. There are only three kinds of
primitives: \type {tex}, \type {etex} and \type {luatex} but a future version
-might drop this and no longer make that distinction as it no longer serves
-a purpose.
-
-\stopsubsection
-
-\startsubsection[title={Experiments}]
-
-There are a few extensions to the engine regarding the macro machinery. Some are
-already well tested but others are (still) experimental. Although they are likely
-to stay, their exact behaviour might evolve. Because \LUAMETATEX\ is also used
-for experiments, this is not a problem. We can always decide to also add some of
-what is discussed here to \LUATEX, but it will happen with a delay.
-
-There are all kinds of small improvements that might find their way into stock
-\LUATEX: a few more helpers, some cleanup of code, etc. We'll see. In any case,
-if you play with these before they are declared stable, unexpected side effects
-are what you have to accept.
+might drop this and no longer make that distinction as it no longer serves a
+purpose apart from the fact that it reveals some history.
\stopsubsection
@@ -83,9 +71,9 @@ There are three primitives to test the version of \LUATEX\ (and \LUAMETATEX):
\BC explanation \NC \NR
\TB
\NC \lpr {luatexbanner} \NC \VersionHack{\luatexbanner}
- \NC the banner reported on the command line \NC \NR
+ \NC the banner reported on the console \NC \NR
\NC \lpr {luatexversion} \NC \the\luatexversion
- \NC a combination of major and minor number \NC \NR
+ \NC major and minor number combined \NC \NR
\NC \lpr {luatexrevision} \NC \the\luatexrevision
\NC the revision number \NC \NR
\LL
@@ -123,17 +111,6 @@ The \LUAMETATEX\ version number starts at~2 in order to prevent a clash with
\LUATEX, and the version commands are the same. This is a way to indicate that
these projects are related.
-\startsubsubsection[title={\lpr {formatname}}]
-
-\topicindex{format}
-
-The \lpr {formatname} syntax is identical to \prm {jobname}. In \INITEX, the
-expansion is empty. Otherwise, the expansion is the value that \prm {jobname} had
-during the \INITEX\ run that dumped the currently loaded format. You can use this
-token list to provide your own version info.
-
-\stopsubsubsection
-
\stopsubsection
\stopsection
@@ -178,7 +155,9 @@ the time comes to print a character $c>=1{,}114{,}112$, \LUATEX\ will actually
print the single byte corresponding to $c$ minus 1{,}114{,}112.
Contrary to other \TEX\ engines, the output to the terminal is as|-|is so there
-is no escaping with \type {^^}. We operate in a \UTF\ universe.
+is no escaping with \type {^^}. We operate in a \UTF\ universe. Because we
+operate in a \CCODE\ universum, zero characters are special but because we also
+live in a \UNICODE\ galaxy that is no real problem.
\stopsubsection
@@ -229,6 +208,34 @@ Fonts are loaded via \LUA\ and a minimal amount of information is kept at the
about what a character (or glyph) number represents (a \UNICODE\ or index) as it
only is interested in dimensions.
+In \TEX\ the number of registers is 256 and \ETEX\ bumped that to 32K. One reason
+for a fixed number is that these registers are fast ways to store data and
+therefore are part of the main lookup table (used for data and pointers to data
+as well as save and restore housekeeping). In \LUATEX\ the number was bumped to
+64K but one can argue that less would also do. In order to keep the default
+memory footprint reasonable, in \LUAMETATEX\ the number of languages, fonts and
+marks is limited. The size of some tables can be limited by configuration
+settings, so they can start out small and grow till configured maximum which is
+smaller than the absolute maximum. The following table shows all kind of defaults
+as reported by \typ {status.getconstants()}.
+
+\startluacode
+ context.starttabulate { "|T|r|" }
+ for k, v in table.sortedhash(status.getconstants()) do
+ context.NC() context(k) context.NC() context(v) context.NC() context.NR()
+ end
+ context.stoptabulate()
+\stopluacode
+
+Because we have additional ways to store integers, dimensions and glue, we might
+actually decide to decrease the maximum of the registers: if 64K is not enough,
+and you work around it, then likely 32K might do as well. Also, we have \LUA\ to
+store massive amounts of data. One can argue that saving some 1.5MB memory (when
+we go halfway) is not worth the effort in a time when you have to close a browser
+in order to free the gigabytes it consumes, but there is no reason not to be lean
+and mean: a more conservative approach to start with creates headroom for going
+wild later.
+
\stopsubsection
\stopsection
@@ -274,6 +281,12 @@ language related information, the expansion factor, etc. Now that we have access
to these nodes from \LUA\ it makes sense to be able to carry more information
with a node and this is where attributes kick in.
+It is important to keep in mind that there are situations where nodes get created
+in the current context. For instance, when \TEX\ builds a paragraph or page or
+constructs math formulas, it does add nodes and giving these the current
+attributes makes no sense and can even give weird side effects. In these cases,
+the attributes are inherited from neighbouring nodes.
+
\stopsubsection
\startsubsection[title={Attribute registers}]
@@ -320,6 +333,7 @@ experimental.
\topicindex {attributes}
\topicindex {boxes}
+\topicindex {vcentering}
Nodes typically receive the list of attributes that is in effect when they are
created. This moment can be quite asynchronous. For example: in paragraph
@@ -343,7 +357,7 @@ already boxed material will have no effect. Keep in mind that this
incompatibility is mostly due to the fact that separate specials and literals are
a more unnatural approach to colors than attributes.
-It is possible to fine-tune the list of attributes that are applied to a \type
+It is possible to fine|-|tune the list of attributes that are applied to a \type
{hbox}, \type {vbox} or \type {vtop} by the use of the keyword \type {attr}. The
\type {attr} keyword(s) should come before a \type {to} or \type {spread}, if
that is also specified. An example is:
@@ -392,6 +406,19 @@ indexing the node (here we do that with \type {[a]}). Running this snippet gives
Because some values are not set we need to apply the \type {tostring} function
here so that we get the word \type {nil}.
+A special kind of box is \prm {vcenter}. This one also can have attributes. When
+one or more are set these plus the currently set attributes are bound to the
+resulting box. In regular \TEX\ these centered boxes are only permitted in math
+mode, but in \LUAMETATEX\ there is no error message and the box the height and
+depth are equally divided. Of course in text mode there is no math axis related
+offset applied.
+
+It is possible to change or add to the attributes assigned to a box:
+
+\starttyping
+\boxattr 0 123 456
+\stoptyping
+
\stopsubsection
\stopsection
@@ -467,20 +494,22 @@ will result in
Note that the expansion of \prm {directlua} is a sequence of characters, not of
tokens, contrary to all \TEX\ commands. So formally speaking its expansion is
-null, but it places material on a pseudo-file to be immediately read by \TEX, as
-\ETEX's \prm {scantokens}. For a description of print functions look at \in
-{section} [sec:luaprint].
+null, but it collects material in a new level on the input stack to be
+immediately read by \TEX\ after the \LUA\ call as finished. It is a bit like
+\ETEX's \prm {scantokens}, which now uses the same mechanism. For a description
+of print functions look at \in {section} [sec:luaprint].
Because the \syntax {<general text>} is a chunk, the normal \LUA\ error handling
is triggered if there is a problem in the included code. The \LUA\ error messages
-should be clear enough, but the contextual information is still pretty bad.
-Often, you will only see the line number of the right brace at the end of the
-code.
+should be clear enough, but the contextual information is often suboptimal
+because it can come from deep down, and \TEX\ has no knowledge about what you do
+in \LUA. Often, you will only see the line number of the right brace at the end
+of the code.
While on the subject of errors: some of the things you can do inside \LUA\ code
can break up \LUAMETATEX\ pretty bad. If you are not careful while working with
-the node list interface, you may even end up with assertion errors from within
-the \TEX\ portion of the executable.
+the node list interface, you may even end up with errors or even crashes from
+within the \TEX\ portion of the executable.
\stopsubsection
@@ -557,6 +586,8 @@ tokens and assume that the function is available when that token expands. On the
other hand, as we have tested this functionality in relative complex situations
normal usage should not give problems.
+{\em It makes sense to delegate the implementation of the primitives to \LUA.}
+
\stopsubsection
\startsubsection[title={\lpr {luabytecode} and \lpr {luabytecodecall}}]
@@ -586,6 +617,8 @@ The variable \type {s} in the code is the number of the byte code register that
can be used for diagnostic purposes. The advantage of bytecode registers over
function calls is that they are stored in the format (but without upvalues).
+{\em It makes sense to delegate the implementation of the primitives to \LUA.}
+
\stopsubsection
\stopsection
@@ -608,14 +641,14 @@ contents is stored and retrieved from the format file.
\startsubsection[title={\lpr {catcodetable}}]
-\startsyntax
-\catcodetable <15-bit number>
-\stopsyntax
-
The primitive \lpr {catcodetable} switches to a different catcode table. Such a
table has to be previously created using one of the two primitives below, or it
has to be zero. Table zero is initialized by \INITEX.
+\startsyntax
+\catcodetable <15-bit number>
+\stopsyntax
+
\stopsubsection
\startsubsection[title={\lpr {initcatcodetable}}]
@@ -655,11 +688,9 @@ initial values are:
\lpr {savecatcodetable} copies the current set of catcodes to a new table with
the requested number. The definitions in this new table are all treated as if
-they were made in the outermost level.
-
-The new table is allocated globally: it will not go away after the current group
-has ended. If the supplied number is the currently active table, an error is
-raised.
+they were made in the outermost level. Again, the new table is allocated globally:
+it will not go away after the current group has ended. If the supplied number is
+the currently active table, an error is raised.
\stopsubsection
@@ -667,7 +698,7 @@ raised.
\startsection[title={Tokens, commands and strings}]
-\startsubsection[title={\lpr {scantextokens}}]
+\startsubsection[title={\lpr {scantextokens} and \lpr {tokenized}}]
\topicindex {tokens+scanning}
@@ -677,8 +708,7 @@ differences are:
\startitemize
\startitem
- The last (and usually only) line does not have a \prm {endlinechar}
- appended.
+ The last (and usually only) line does not have a \prm {endlinechar} appended.
\stopitem
\startitem
\lpr {scantextokens} never raises an EOF error, and it does not execute
@@ -691,6 +721,18 @@ differences are:
\stopitem
\stopitemize
+The implementation in \LUAMETATEX\ is different in the sense that it uses the same
+methods as printing from \LUA\ to \TEX\ does. Therefore, in addition to the two
+commands we also have this expandable command:
+
+\startsyntax
+\tokenized {...}
+\tokenized catcodetable <number> {...}
+\stopsyntax
+
+The \ETEX\ command \type {\tracingscantokens} has been dropped in the process as
+that was interwoven with the old code.
+
\stopsubsection
\startsubsection[title={\lpr {toksapp}, \lpr {tokspre}, \lpr {etoksapp}, \lpr {etokspre},
@@ -750,7 +792,7 @@ that it saves a few tokens and can make code a bit more readable.
This primitive complements the \ETEX\ mark primitives and clears a mark class
completely, resetting all three connected mark texts to empty. It is an
-immediate command.
+immediate command (no synchronization node is used).
\startsyntax
\clearmarks <16-bit number>
@@ -792,103 +834,135 @@ but faster (only measurable with millions of calls) and probably more convenient
\stopsubsection
-\startsubsection[title={\lpr {expanded}, \lpr {immediateassignment} and \lpr {immediateassigned}}]
-
-\topicindex {expansion}
-
-The \lpr {expanded} primitive takes a token list and expands its content which can
-come in handy: it avoids a tricky mix of \prm {expandafter} and \prm {noexpand}.
-You can compare it with what happens inside the body of an \prm {edef}. But this
-kind of expansion still doesn't expand some primitive operations.
-
-\startbuffer
-\newcount\NumberOfCalls
-
-\def\TestMe{\advance\NumberOfCalls1 }
-
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-
-\meaning\Tested
-\stopbuffer
-
-\typebuffer
-
-The result is a macro that has the not expanded code in its body:
-
-\getbuffer
-
-Instead we can define \tex {TestMe} in a way that expands the assignment
-immediately. You need of course to be aware of preventing look ahead interference
-by using a space or \tex {relax} (often an expression works better as it doesn't
-leave an \tex {relax}).
-
-\startbuffer
-\def\TestMe{\immediateassignment\advance\NumberOfCalls1 }
+\startsubsection[title={\lpr {defcsname}, \lpr {edefcsname}, \lpr {edefcsname} and \lpr {xdefcsname}}]
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+Although we can implement these primitives easily using macros it makes sense,
+given the popularity of \prm {csname} to have these as primitives. It also saves
+some \prm {expandafter} usage and it looks a bit better in the source.
-\meaning\Tested
-\stopbuffer
-
-\typebuffer
-
-This time the counter gets updates and we don't see interference in the
-resulting \tex {Tested} macro:
-
-\getbuffer
-
-Here is a somewhat silly example of expanded comparison:
-
-\startbuffer
-\def\expandeddoifelse#1#2#3#4%
- {\immediateassignment\edef\tempa{#1}%
- \immediateassignment\edef\tempb{#2}%
- \ifx\tempa\tempb
- \immediateassignment\def\next{#3}%
- \else
- \immediateassignment\def\next{#4}%
- \fi
- \next}
-
-\edef\Tested
- {(\expandeddoifelse{abc}{def}{yes}{nop}/%
- \expandeddoifelse{abc}{abc}{yes}{nop})}
-
-\meaning\Tested
-\stopbuffer
+\starttyping
+\def\gdefcsname foo\endcsname{oof}
+\stoptyping
-\typebuffer
+\stopsubsection
-It gives:
+\startsubsection[title={\lpr {expanded}}]
-\getbuffer
+\topicindex {expansion}
-A variant is:
+The \lpr {expanded} primitive takes a token list and expands its content which
+can come in handy: it avoids a tricky mix of \prm {expandafter} and \prm
+{noexpand}. You can compare it with what happens inside the body of an \prm
+{edef}. The \tex {immediateassignment} and \tex {immediateassigned} commands are
+gone because we have the more powerful local control commands. They are a tad
+slower but this mechanism isn't used that much anyway. Inside an \prm {edef} you
+can use the \type {\immediate} prefix anyway, so if you really want these
+primitives back you can say:
\starttyping
-\def\expandeddoifelse#1#2#3#4%
- {\immediateassigned{
- \edef\tempa{#1}%
- \edef\tempb{#2}%
- }%
- \ifx\tempa\tempb
- \immediateassignment\def\next{#3}%
- \else
- \immediateassignment\def\next{#4}%
- \fi
- \next}
+\let\immediateassignment\immediate
+\let\immediateassigned \localcontrolled
\stoptyping
-The possible error messages are the same as using assignments in preambles of
-alignments and after the \prm {accent} command. The supported assignments are the
-so called prefixed commands (except box assignments).
-
\stopsubsection
+% \startsubsection[title={\lpr {expanded}, \lpr {immediateassignment} and \lpr {immediateassigned}}]
+%
+% \topicindex {expansion}
+%
+% The \lpr {expanded} primitive takes a token list and expands its content which can
+% come in handy: it avoids a tricky mix of \prm {expandafter} and \prm {noexpand}.
+% You can compare it with what happens inside the body of an \prm {edef}. But this
+% kind of expansion still doesn't expand some primitive operations.
+%
+% \startbuffer
+% \newcount\NumberOfCalls
+%
+% \def\TestMe{\advance\NumberOfCalls1 }
+%
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+%
+% \meaning\Tested
+% \stopbuffer
+%
+% \typebuffer
+%
+% The result is a macro that has the not expanded code in its body:
+%
+% \getbuffer
+%
+% Instead we can define \tex {TestMe} in a way that expands the assignment
+% immediately. You need of course to be aware of preventing look ahead interference
+% by using a space or \tex {relax} (often an expression works better as it doesn't
+% leave an \tex {relax}).
+%
+% \startbuffer
+% \def\TestMe{\immediateassignment\advance\NumberOfCalls1 }
+%
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+%
+% \meaning\Tested
+% \stopbuffer
+%
+% \typebuffer
+%
+% This time the counter gets updates and we don't see interference in the
+% resulting \tex {Tested} macro:
+%
+% \getbuffer
+%
+% Here is a somewhat silly example of expanded comparison:
+%
+% \startbuffer
+% \def\expandeddoifelse#1#2#3#4%
+% {\immediateassignment\edef\tempa{#1}%
+% \immediateassignment\edef\tempb{#2}%
+% \ifx\tempa\tempb
+% \immediateassignment\def\next{#3}%
+% \else
+% \immediateassignment\def\next{#4}%
+% \fi
+% \next}
+%
+% \edef\Tested
+% {(\expandeddoifelse{abc}{def}{yes}{nop}/%
+% \expandeddoifelse{abc}{abc}{yes}{nop})}
+%
+% \meaning\Tested
+% \stopbuffer
+%
+% \typebuffer
+%
+% It gives:
+%
+% \getbuffer
+%
+% A variant is:
+%
+% \starttyping
+% \def\expandeddoifelse#1#2#3#4%
+% {\immediateassigned{
+% \edef\tempa{#1}%
+% \edef\tempb{#2}%
+% }%
+% \ifx\tempa\tempb
+% \immediateassignment\def\next{#3}%
+% \else
+% \immediateassignment\def\next{#4}%
+% \fi
+% \next}
+% \stoptyping
+%
+% The possible error messages are the same as using assignments in preambles of
+% alignments and after the \prm {accent} command. The supported assignments are the
+% so called prefixed commands (except box assignments).
+%
+% \stopsubsection
+
\startsubsection[title={\lpr {ignorepars}}]
This primitive is like \prm {ignorespaces} but also skips paragraph ending
@@ -1034,6 +1108,55 @@ or more than zero.
\typebuffer \blank {\tt \getbuffer} \blank
+The last checked values are available in \lpr {lastchknum} and \lpr {lastchkdim}.
+These don't obey grouping.
+
+\stopsubsection
+
+\startsubsection[title={\lpr {ifmathstyle} and \lpr {ifmathparameter}}]
+
+These two are variants on \prm {ifcase} where the first one operates with values
+in ranging from zero (display style) to seven (cramped script script style) and
+the second one can have three values: a parameter is zero, has a value or is
+unset. The \type {\ifmathparameter} primitive takes a proper parameter name and a
+valid style identifier (a primitive identifier or number). The \type
+{\ifmathstyle} primitive is equivalent to \type {\ifcase \mathstyle}.
+
+\stopsubsection
+
+\startsubsection[title={\lpr {ifempty}}]
+
+This primitive tests for the following token (control sequence) having no
+content. Assuming that \type {\empty} is indeed empty, the following two are
+equivalent:
+
+\starttyping
+\ifempty\whatever
+\ifx\whatever\empty
+\stoptyping
+
+There is no real performance gain here, it's more one of these extensions that
+lead to less clutter in tracing.
+
+\stopsubsection
+
+\startsubsection[title={\lpr {ifrelax}}]
+
+This primitive complements \type {\ifdefined}, \type {\ifempty} and \type
+{\ifcsname} so that we have all reasonable tests directly available.
+
+\stopsubsection
+
+\startsubsection[title={\lpr {ifboolean}}]
+
+This primitive tests for non|-|zero, so the next variants are similar
+
+\starttyping
+ \ifcase <integer>.F.\else .T.\fi
+\unless\ifcase <integer>.T.\else .F.\fi
+ \ifboolean<integer>.T.\else .F.\fi
+\stoptyping
+
\stopsubsection
\startsubsection[title={\lpr {iftok} and \lpr {ifcstok}}]
@@ -1058,13 +1181,40 @@ provided in \LUAMETATEX:
\typebuffer \startpacked[blank] {\tt\nospacing\getbuffer} \stoppacked
-You can check if a macro is is defined as protected with \type {\ifprotected}
-while frozen macros can be tested with \type {\iffrozen}. A provisional \type
+You can check if a macro is defined as protected with \type {\ifprotected} while
+frozen macros can be tested with \type {\iffrozen}. A provisional \type
{\ifusercmd} tests will check if a command is defined at the user level (and this
one might evolve).
\stopsubsection
+\startsubsection[title={\lpr {ifarguments}, \lpr {ifparameters} and \lpr {ifparameter}}]
+
+These are part of the extended macro argument parsing features. The \type
+{\ifarguments} condition is like an \type {\ifcase} where the number is the
+picked up number of arguments. The number reflects the {\em last} count, so
+successive macro expansions will adapt the value. The \type {\ifparameters}
+counts till the first empty parameter and the \type {\ifparameter} (singular)
+takes a parameter reference (like \type {#2}) and again is an \type {\ifcase}
+where zero means a bad reference, one a non|-|empty argument and two an empty
+one. A typical usage is:
+
+\starttyping
+\def\foo#1#2%
+ {\ifparameter#1\or one\fi
+ \ifparameter#2\or two\fi}
+\stoptyping
+
+No expansion of arguments takes place here but you can use a test like this:
+
+\starttyping
+\def\foo#1#2%
+ {\iftok{#1}{}\else one\fi
+ \iftok{#2}{}\else two\fi}
+\stoptyping
+
+\stopsubsection
+
\startsubsection[title={\lpr {ifcondition}}]
\topicindex {conditions}
@@ -1123,7 +1273,7 @@ we use \type {\unless} to negate the result.
\stopsubsection
-\startsubsection[title={\lpr {orelse}}]
+\startsubsection[title={\lpr {orelse} and \lpr {orunless}}]
Sometimes you have successive tests that, when laid out in the source lead to
deep trees. The \type {\ifcase} test is an exception. Experiments with \type
@@ -1189,6 +1339,12 @@ Of course it is only useful at the right level, so you might end up with cases l
\fi
\stoptyping
+The \lpr {orunless} variant negates the next test, just like \prm {unless}. In
+some cases these commands look at the next token to see if it is an if|-|test so
+a following negation will not work (read: making that work would complicate the
+code and hurt efficiency too). Side note: interesting is that in \CONTEXT\ we
+hardly use this kind of negation.
+
\stopsubsection
\startsubsection[title={\lpr {ifprotected}, \lpr {frozen}, \lpr {iffrozen} and \lpr {ifusercmd}}]
@@ -1219,10 +1375,18 @@ the acceptable range is from 0 to 65535.
\stopsubsection
-\startsubsection[title={\prm {vpack}, \prm {hpack} and \prm {tpack}}]
+\startsubsection[title={\prm {hrule}, \prm {vrule}, \lpr {nohrule} and \lpr {novrule}}]
+
+\topicindex {rules}
+
+Both rule drawing commands take an optional \type {xoffset} and \type {yoffset}
+parameter. The displacement is virtual and not taken into account when the
+dimensions are calculated.
-These three primitives are like \prm {vbox}, \prm {hbox} and \prm {vtop}
-but don't apply the related callbacks.
+Two new primitives were introduced: \lpr {nohrule} and \lpr {novrule}. These can
+be used to reserve space. This is often more efficient than creating an empty box
+with fake dimensions. Of course this assumes that the backend implements them
+being invisible but still taking space.
\stopsubsection
@@ -1236,7 +1400,7 @@ a split of the given size but result has the natural dimensions then.
\stopsubsection
-\startsubsection[title={Images and reused box objects},reference=sec:imagedandforms]
+\startsubsection[title={Images and reused box objects},reference=sec:imagesandforms]
In original \TEX\ image support is dealt with via specials. It's not a native
feature of the engine. All that \TEX\ cares about is dimensions, so in practice
@@ -1252,12 +1416,12 @@ point this approach was abandoned and a more natural trick was used: images (and
box resources) became a special kind of rules, and as rules already have
dimensions, the code could be simplified.
-When direction nodes and localpar nodes also became first class nodes, whatsits
-again became just that: nodes representing whatever you want, but without
-dimensions, and therefore they could again be ignored when dimensions mattered.
-And, because images were disguised as rules, as mentioned, their dimensions
-automatically were taken into account. This seperation between front and backend
-cleaned up the code base already quite a bit.
+When direction nodes and (formerly local) par nodes also became first class
+nodes, whatsits again became just that: nodes representing whatever you want, but
+without dimensions, and therefore they could again be ignored when dimensions
+mattered. And, because images were disguised as rules, as mentioned, their
+dimensions automatically were taken into account. This separation between front
+and backend cleaned up the code base already quite a bit.
In \LUAMETATEX\ we still have the image specific subtypes for rules, but the
engine never looks at subtypes of rules. That was up to the backend. This means
@@ -1313,21 +1477,12 @@ packages.
\startsubsection[title={\lpr {hpack}, \lpr {vpack} and \lpr {tpack}}]
-These three primitives are the equivalents of \type {\hbox}, \type {\vbox} and
-\type {\vtop} but they don't trigger the packaging related callbacks. Of course
+These three primitives are the equivalents of \prm {hbox}, \prm {vbox} and
+\prm {vtop} but they don't trigger the packaging related callbacks. Of course
one never know if content needs a treatment so using them should be done with
-care.
-
-\stopsubsection
-
-\startsubsection[title={\lpr {nohrule} and \lpr {novrule}}]
-
-\topicindex {rules}
-
-Because introducing a new keyword can cause incompatibilities, two new primitives
-were introduced: \lpr {nohrule} and \lpr {novrule}. These can be used to
-reserve space. This is often more efficient than creating an empty box with fake
-dimensions.
+care. Apart from accepting more keywords (and therefore options) the normal
+box behave the same as before. The \prm {vcenter} builder also works in text
+mode.
\stopsubsection
@@ -1390,14 +1545,29 @@ the node number of the nodes.
\stopsubsection
+% \startsubsection[title={\lpr {lastnodetype}, \lpr {lastnodesubtype}, \lpr
+% {currentiftype} and \lpr {internalcodesmode}.}]
+%
+% The \ETEX\ command \type {\lastnodetype} is limited to some nodes. When the
+% parameter \type {\internalcodesmode} is set to a non|-|zero value the normal
+% (internally used) numbers are reported. The same is true for \type
+% {\currentiftype}, as we have more conditionals and also use a different order.
+% The \type {\lastnodesubtype} is a bonus.
+%
+% \stopsubsection
+
\startsubsection[title={\lpr {lastnodetype}, \lpr {lastnodesubtype}, \lpr
-{currentiftype} and \lpr {internalcodesmode}.}]
+{currentiftype}}]
-The \ETEX\ command \type {\lastnodetype} is limited to some nodes. When the
-parameter \type {\internalcodesmode} is set to a non|-|zero value the normal
-(internally used) numbers are reported. The same is true for \type
+The \ETEX\ command \type {\lastnodetype} returns the node codes as used in the
+engine. You can query the numbers at the \LUA\ end if you need the actual values.
+The parameter \type {\internalcodesmode} is no longer provided as compatibility
+switch because \LUATEX\ has more cq. some different nodes and it makes no sense
+to be incompatible with the \LUA\ end of the engine. The same is true for \type
{\currentiftype}, as we have more conditionals and also use a different order.
-The \type {\lastnodesubtype} is a bonus.
+The \type {\lastnodesubtype} is a bonus and again reports the codes used
+internally. During development these might occasionally change, but eventually
+they will be stable.
\stopsubsection
@@ -1417,7 +1587,10 @@ The \type {\lastnodesubtype} is a bonus.
\stoptyping
This allows for embedded spaces, without the need for double quotes. Macro
-expansion takes place inside the argument.
+expansion takes place inside the argument. Keep in mind that as side effect of
+delegating \IO\ to \LUA\ the \prm {openin} primitive is nor provided by the
+engine and has to be implemented by the macro package. This also means that the
+limit on the number of open files is not enforced by the engine.
The \lpr {tracingfonts} primitive that has been inherited from \PDFTEX\ has
been adapted to support variants in reporting the font. The reason for this
@@ -1442,10 +1615,12 @@ extension is that a csname not always makes sense. The zero case is the default.
\topicindex {files+writing}
-You can now open upto 127 files with \prm {openout}. When no file is open writes
-will go to the console and log. The \type {write} related primitives have to be
-implemented as part of a backend! As a consequence a system command is no longer
-possible but one can use \type {os.execute} to do the same.
+Writing to a file in \TEX\ has two forms: delayed and immediate. Delayed writing
+means that the to be written text is anchored in the node list and flushed by the
+backend. As all \IO\ is delegated to \LUA, this also means that it has to deal
+with distinction. In \LUATEX\ the number of open files was already bumped to 127,
+but in \LUAMETATEX\ it depends on the macro package. The special meaning of
+channel 18 was already dropped in \LUATEX\ because we have \type {os.execute}.
\stopsubsection
@@ -1617,106 +1792,143 @@ convenience extra which could also have been implemented using node list parsing
\stopsubsection
-\startsubsection[title={Controlling glue with \lpr {breakafterdirmode}}]
+\startsubsection[title={Normalizing lines}]
-Glue after a dir node is ignored in the linebreak decision but you can bypass that
-by setting \lpr {breakafterdirmode} to~\type {1}. The following table shows the
-difference. Watch your spaces.
+The original \TEX\ machinery was never meant to be opened up. As a consequence a
+constructed line can have different layouts. There can be left- and/or right
+skips and hanging indentation or parshape can result in a shift and adapted
+width. In \LUATEX\ glue got subtypes so we can recognize the left-, right and
+parfill skips, but still there is no hundred percent certainty about the shape.
-\def\ShowSome#1{%
- \BC \type{#1}
- \NC \breakafterdirmode\zerocount\hsize\zeropoint#1
- \NC
- \NC \breakafterdirmode\plusone\hsize\zeropoint#1
- \NC
- \NC \NR
-}
+In \LUAMETATEX\ lines can be normalized. This is optional because we want to
+preserve the original (for comparison) and is controlled by \lpr
+{normalizelinemode}. That variable actually drives some more. An earlier version
+provided a few more granular options (for instance: does a leftskip comes before
+or after a left hanging indentation) but in the end that was dropped. Because
+this normalization only is seen at the \LUA\ end there is no need to go into much
+detail here.
-\starttabulate[|l|Tp(1pt)|w(5em)|Tp(1pt)|w(5em)|]
- \DB
- \BC \type{0}
- \NC
- \BC \type{1}
- \NC
- \NC \NR
- \TB
- \ShowSome{pre {\textdirection 0 xxx} post}
- \ShowSome{pre {\textdirection 0 xxx }post}
- \ShowSome{pre{ \textdirection 0 xxx} post}
- \ShowSome{pre{ \textdirection 0 xxx }post}
- \ShowSome{pre { \textdirection 0 xxx } post}
- \ShowSome{pre {\textdirection 0\relax\space xxx} post}
- \LL
-\stoptabulate
+At this moment a line has this pattern: left parfill, left hang, left skip,
+indentation, content, right hang, right skip, right parfill. Of course the
+indentation and fill skips are not present in every line.
-\stopsubsection
+Control over normalization happens via the mentioned mode variable and here is
+what the engine provides right now. We use a bitmap:
-\startsubsection[title={Controling parshapes with \lpr {shapemode}}]
-
-Another adaptation to the \ALEPH\ directional model is control over shapes driven
-by \prm {hangindent} and \prm {parshape}. This is controlled by a new parameter
-\lpr {shapemode}:
-
-\starttabulate[|c|l|l|]
-\DB value \BC \prm {hangindent} \BC \prm {parshape} \NC \NR
+\starttabulate[|l|l|]
+\DB value \BC reported \NC \NR
\TB
-\BC \type{0} \NC normal \NC normal \NC \NR
-\BC \type{1} \NC mirrored \NC normal \NC \NR
-\BC \type{2} \NC normal \NC mirrored \NC \NR
-\BC \type{3} \NC mirrored \NC mirrored \NC \NR
+\NC \type{0x0001} \NC normalize line as described above \NC \NR
+\NC \type{0x0002} \NC use a skip for parindent instead of a box \NC \NR
+\NC \type{0x0004} \NC swap hangindent in l2r mode \NC \NR
+\NC \type{0x0008} \NC swap parshape in l2r mode \NC \NR
+\NC \type{0x0010} \NC put breaks after dir in l2r mode \NC \NR
+\NC \type{0x0020} \NC remove margin kerns (\PDFTEX\ left-over) \NC \NR
+\NC \type{0x0040} \NC if needed clip width and use correction kern \NC \NR
\LL
\stoptabulate
-The value is reset to zero (like \prm {hangindent} and \prm {parshape})
-after the paragraph is done with. You can use negative values to prevent
-this. In \in {figure} [fig:shapemode] a few examples are given.
-
-\startplacefigure[reference=fig:shapemode,title={The effect of \type {shapemode}.}]
- \startcombination[2*3]
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \pardirection 0 \textdirection 0
- \hangindent 40pt \hangafter -3
- \leftskip10pt \input tufte \par
- \egroup} {TLT: hangindent}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \pardirection 0 \textdirection 0
- \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
- \input tufte \par
- \egroup} {TLT: parshape}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \pardirection 1 \textdirection 1
- \hangindent 40pt \hangafter -3
- \leftskip10pt \input tufte \par
- \egroup} {TRT: hangindent mode 0}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \pardirection 1 \textdirection 1
- \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
- \input tufte \par
- \egroup} {TRT: parshape mode 0}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \shapemode=3
- \pardirection 1 \textdirection 1
- \hangindent 40pt \hangafter -3
- \leftskip10pt \input tufte \par
- \egroup} {TRT: hangindent mode 1 & 3}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \shapemode=3
- \pardirection 1 \textdirection 1
- \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
- \input tufte \par
- \egroup} {TRT: parshape mode 2 & 3}
- \stopcombination
-\stopplacefigure
-
-We have \type {\pardirection}, \type {\textdirection}, \type {\mathdirection} and
-\type {\linedirection} that is like \type {\textdirection} but with some
-additional (inline) glue checking.
+Setting the bit enables the related normalization. More features might be added
+in future releases.
+
+% Swapping shapes
+%
+% Another adaptation to the \ALEPH\ directional model is control over shapes driven
+% by \prm {hangindent} and \prm {parshape}. This is controlled by a new parameter
+% \lpr {shapemode}:
+%
+% \starttabulate[|c|l|l|]
+% \DB value \BC \prm {hangindent} \BC \prm {parshape} \NC \NR
+% \TB
+% \BC \type{0} \NC normal \NC normal \NC \NR
+% \BC \type{1} \NC mirrored \NC normal \NC \NR
+% \BC \type{2} \NC normal \NC mirrored \NC \NR
+% \BC \type{3} \NC mirrored \NC mirrored \NC \NR
+% \LL
+% \stoptabulate
+%
+% The value is reset to zero (like \prm {hangindent} and \prm {parshape})
+% after the paragraph is done with. You can use negative values to prevent
+% this. In \in {figure} [fig:shapemode] a few examples are given.
+%
+% \startplacefigure[reference=fig:shapemode,title={The effect of \type {shapemode}.}]
+% \startcombination[2*3]
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \pardirection 0 \textdirection 0
+% \hangindent 40pt \hangafter -3
+% \leftskip10pt \input tufte \par
+% \egroup} {TLT: hangindent}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \pardirection 0 \textdirection 0
+% \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
+% \input tufte \par
+% \egroup} {TLT: parshape}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \pardirection 1 \textdirection 1
+% \hangindent 40pt \hangafter -3
+% \leftskip10pt \input tufte \par
+% \egroup} {TRT: hangindent mode 0}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \pardirection 1 \textdirection 1
+% \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
+% \input tufte \par
+% \egroup} {TRT: parshape mode 0}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \shapemode=3
+% \pardirection 1 \textdirection 1
+% \hangindent 40pt \hangafter -3
+% \leftskip10pt \input tufte \par
+% \egroup} {TRT: hangindent mode 1 & 3}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \shapemode=3
+% \pardirection 1 \textdirection 1
+% \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
+% \input tufte \par
+% \egroup} {TRT: parshape mode 2 & 3}
+% \stopcombination
+% \stopplacefigure
+%
+% We have \type {\pardirection}, \type {\textdirection}, \type {\mathdirection} and
+% \type {\linedirection} that is like \type {\textdirection} but with some
+% additional (inline) glue checking.
+
+% Controlling glue with \lpr {breakafterdirmode}
+%
+% Glue after a dir node is ignored in the linebreak decision but you can bypass that
+% by setting \lpr {breakafterdirmode} to~\type {1}. The following table shows the
+% difference. Watch your spaces.
+%
+% \def\ShowSome#1{%
+% \BC \type{#1}
+% \NC \breakafterdirmode\zerocount\hsize\zeropoint#1
+% \NC
+% \NC \breakafterdirmode\plusone\hsize\zeropoint#1
+% \NC
+% \NC \NR
+% }
+%
+% \starttabulate[|l|Tp(1pt)|w(5em)|Tp(1pt)|w(5em)|]
+% \DB
+% \BC \type{0}
+% \NC
+% \BC \type{1}
+% \NC
+% \NC \NR
+% \TB
+% \ShowSome{pre {\textdirection 0 xxx} post}
+% \ShowSome{pre {\textdirection 0 xxx }post}
+% \ShowSome{pre{ \textdirection 0 xxx} post}
+% \ShowSome{pre{ \textdirection 0 xxx }post}
+% \ShowSome{pre { \textdirection 0 xxx } post}
+% \ShowSome{pre {\textdirection 0\relax\space xxx} post}
+% \LL
+% \stoptabulate
\stopsubsection
@@ -1751,17 +1963,286 @@ shows that is't okay, they will become official, so we just mention them: \type
{\boxdirection}, \type {\boxattr}, \type {\boxorientation}, \type {\boxxoffset},
\type {\boxyoffset}, \type {\boxxmove}, \type {\boxymove} and \type {\boxtotal}.
+{\em This is still somewhat experimental and will be documented in more detail
+when I've used it more in \CONTEXT\ and the specification is frozen. This might
+take some time (and user input).}
+
\stopsubsection
\stopsection
-\startsection[title=Expressions]
+\startsection[title=Keywords]
+
+Some primitives accept one or more keywords and \LUAMETATEX\ adds some more. In
+order to deal with this efficiently the keyword scanner has been optimized, where
+even the context was taken into account. As a result the scanner was quite a bit
+faster. This kind of optimization was a graduate process the eventually ended up
+in what we have now. In traditional \TEX\ (and also \LUATEX) the order of
+keywords is sometimes mixed and sometimes prescribed. In most cases only one
+occurrence is permitted. So, for instance, this is valid in \LUATEX:
+
+\starttyping
+\hbox attr 123 456 attr 123 456 spread 10cm { }
+\hrule width 10cm depth 3mm
+\hskip 3pt plus 2pt minus 1pt
+\stoptyping
+
+The \type {attr} comes before the \type {spread}, rules can have multiple mixed
+dimension specifiers, and in glue the optional \type {minus} part always comes
+last. The last two commands are famous for look ahead side effects which is why
+macro packages will end them with something not keyword, like \type {\relax},
+when needed.
+
+In \LUAMETATEX\ the following is okay. Watch the few more keywords in box and
+rule specifications.
+
+\starttyping
+\hbox reverse to 10cm attr 123 456 orientation 4 xoffset 10pt spread 10cm { }
+\hrule xoffset 10pt width 10cm depth 3mm
+\hskip 3pt minus 1pt plus 2pt
+\stoptyping
+
+Here the order is not prescribed and, as demonstrated with the box specifier, for
+instance dimensions (specified by \type {to} or \type {spread} can be overloaded
+by later settings. In case you wonder if that breaks compatibility: in some way
+it does but bad or sloppy keyword usage breaks a run anyway. For instance \type
+{minuscule} results in \type {minus} with no dimension being seen. So, in the end
+the user should not noticed it and when a user does, the macro package already
+had an issue that had to be fixed.
+
+\stopsection
+
+\startsection[title=Expressions and \lpr {numericscale}]
The \type {*expr} parsers now accept \type {:} as operator for integer division
(the \type {/} operators does rounding. This can be used for division compatible
with \type {\divide}. I'm still wondering if adding a couple of bit operators
makes sense (for integers).
+The \lpr{numericscale} parser is kind of special (and might evolve). For now it
+converts a following number in a scale value as often used in \TEX, where 1000
+means scaling by~1.0. The trick is in the presence of a digit (or comma): 1.234
+becomes 1234 but 1234 stays 1234 and from this you can deduce that 12.34 becomes
+123400. Internally \TEX\ calculates with integers, but this permits the macro
+package to provide an efficient mix.
+
+\stopsection
+
+\startsection[title=Macro arguments]
+
+Again this is experimental and (used and) discussed in document that come with the
+\CONTEXT\ distribution. When defining a macro you can do this:
+
+\starttyping
+\def\foo(#1)#2{...}
+\stoptyping
+
+Here the first argument between parentheses is mandate. But the magic
+prefix \lpr {tolerant} makes that limitation go away:
+
+\starttyping
+\tolerant\def\foo(#1)#2{...}
+\stoptyping
+
+A variant is this:
+
+\starttyping
+\tolerant\def\foo(#1)#*(#2){...}
+\stoptyping
+
+Here we have two optional arguments, possibly be separated by spaces. There are
+more parsing options:
+
+\starttabulate[|T|i2l|]
+\FL
+\NC + \NC keep the braces \NC \NR
+\NC - \NC discard and don't count the argument \NC \NR
+\NC / \NC remove leading an trailing spaces and pars \NC \NR
+\NC = \NC braces are mandate \NC \NR
+\NC _ \NC braces are mandate and kept \NC \NR
+\NC ^ \NC keep leading spaces \NC \NR
+\ML
+\NC 1-9 \NC an argument \NC \NR
+\NC 0 \NC discard but count the argument \NC \NR
+\ML
+\NC * \NC ignore spaces \NC \NR
+\NC : \NC pick up scanning here \NC \NR
+\NC ; \NC quit scanning \NC \NR
+\LL
+\stoptabulate
+
+For the moment we leave it to your fantasy what these options do. Most probably
+only make sense when you write a bit more complex macros. Just try to imagine
+what this does:
+
+\starttyping
+\permanent\tolerant\global\protected\def\foo(#1)#*#;[#2]#:#3{...}
+\stoptyping
+
+Of course complex combinations can be confusing because after all \TEX\ is
+parsing for (multi|-|token) delimiters and will happily gobble the whole file if
+you are not careful. You can quit scanning if you want:
+
+\starttyping
+\mymacro 123\ignorearguments
+\stoptyping
+
+which of course only makes sense when used in a nested call where an already
+picked up arguments is processed further. A not (yet) discussed feature of the
+parser is that it will happily skip tokens that have the (probably seldom used)
+ignored characters property.
+
+When you use tracing or see error messages arguments defined using for instance
+\type {#=} will have their usual number in the macro body, so you need to keep
+track of the numbers.
+
+All this is rather easy on the engine and although it might have a little impact
+on performance this has been compensated by some more efficiency in the macro
+parser and engine in general and of course you can gain back some by using these
+features.
+
+\stopsection
+
+\startsection[title=Overload protection]
+
+There is an experimental overload protection mechanism that we will test for a
+while before declaring it stable. The reason for that is that we need to adapt
+the \CONTEXT\ code base in order to test its usefulness. Protection is achieved
+via prefixes. Depending on the value of the \lpr {overloadmode} variable
+warnings or errors will be triggered. Examples of usage can be found in some
+documents that come with \CONTEXT, so here we just stick to the basics.
+
+\starttyping
+\mutable \def\foo{...}
+\immutable\def\foo{...}
+\permanent\def\foo{...}
+\frozen \def\foo{...}
+\aliased \def\foo{...}
+\stoptyping
+
+A \lpr {mutable} macro can always be changed contrary to an \lpr {immutable} one.
+For instance a macro that acts as a variable is normally \lpr {mutable}, while a
+constant can best be immutable. It makes sense to define a public core macro as
+\lpr {permanent}. Primives start out a \lpr {permanent} ones but with a primitive
+property instead.
+
+\startbuffer
+ \let\relaxone \relax 1: \meaningfull\relaxone
+\aliased \let\relaxtwo \relax 2: \meaningfull\relaxtwo
+\permanent\let\relaxthree\relax 3: \meaningfull\relaxthree
+\stopbuffer
+
+\typebuffer
+
+The \lpr {meaningfull} primitive is like \prm {meaning} but report the
+properties too. The \lpr {meaningless} companion reports the body of a macro.
+Anyway, this typesets:
+
+\startlines \tttf \getbuffer \stoplines
+
+So, the \lpr {aliased} prefix copies the properties. Keep in mind that a macro
+package can redefine primitives, but \prm {relax} is an unlikely candidate.
+
+There is an extra prefix \lpr {noaligned} that flags a macro as being valid
+for \prm {noalign} compatible usage (which means that the body must contain that
+one. The idea is that we then can do this:
+
+\starttyping
+\permanent\protected\noaligned\def\foo{\noalign{...}} % \foo is unexpandable
+\stoptyping
+
+that is: we can have protected macros that don't trigger an error in the parser
+where there is a look ahead for \prm {noalign} which is why normally protection
+doesn't work well. So: we have macro flagged as permanent (overload protection),
+being protected (that is, not expandable by default) and a valid equivalent of
+the noalign primitive. Of course we can also apply the \prm {global} and \lpr
+{tolerant} prefixes here. The complete repertoire of extra prefixes is:
+
+\starttabulate
+\HL
+\NC \type {frozen} \NC a macro that has to be redefined in a managed way \NC \NR
+\NC \type {permanent} \NC a macro that had better not be redefined \NC \NR
+\NC \type {primitive} \NC a primitive that normally will not be adapted \NC \NR
+\NC \type {immutable} \NC a macro or quantity that cannot be changed, it is a constant \NC \NR
+\NC \type {mutable} \NC a macro that can be changed no matter how well protected it is \NC \NR
+\HL
+\NC \type {instance} \NC a macro marked as (for instance) be generated by an interface \NC \NR
+\HL
+\NC \type {noaligned} \NC the macro becomes acceptable as \type {\noalign} alias \NC \NR
+\HL
+\NC \type {overloaded} \NC when permitted the flags will be adapted \NC \NR
+\NC \type {enforced} \NC all is permitted (but only in zero mode or ini mode) \NC \NR
+\NC \type {aliased} \NC the macro gets the same flags as the original \NC \NR
+\HL
+\stoptabulate
+
+The not yet discussed \lpr {instance} is just a flag with no special meaning
+which can be used as classifier. The \lpr {frozen} also protects against overload
+which brings amount of blockers to four.
+
+To what extent the engine will complain when a property is changed in a way that
+violates the flags depends on the parameter \lpr {overloadmode}. When this
+parameter is set to zero no checking takes place. More interesting are values
+larger than zero. If that is the case, when a control sequence is flagged as
+mutable, it is always permitted to change. When it is set to immutable one can
+never change it. The other flags determine the kind of checking done. Currently
+the following overload values are used:
+
+\starttabulate[|l|l|c|c|c|c|c|]
+ \NC \NC \BC immutable \BC permanent \BC primitive \BC frozen \BC instance \NC \NR
+ \NC 1 \NC warning \NC \star \NC \star \NC \star \NC \NC \NC \NR
+ \NC 2 \NC error \NC \star \NC \star \NC \star \NC \NC \NC \NR
+ \NC 3 \NC warning \NC \star \NC \star \NC \star \NC \star \NC \NC \NR
+ \NC 4 \NC error \NC \star \NC \star \NC \star \NC \star \NC \NC \NR
+ \NC 5 \NC warning \NC \star \NC \star \NC \star \NC \star \NC \star \NC \NR
+ \NC 6 \NC error \NC \star \NC \star \NC \star \NC \star \NC \star \NC \NR
+\stoptabulate
+
+The even values (except zero) will abort the run. A value of 255 will freeze this
+parameter. At level five and above the \lpr {instance} flag is also checked but
+no drastic action takes place. We use this to signal to the user that a specific
+instance is redefined (of course the definition macros can check for that too).
+
+The \lpr {overloaded} prefix can be used to overload a frozen macro. The \lpr
+{enforced} is more powerful and forces an overload but that prefix is only
+effective in ini mode or when it's embedded in the body of a macro or token list
+at ini time unless of course at runtime the mode is zero.
+
+So far for a short explanation. More details can be found in the \CONTEXT\
+documentation where we can discuss it in a more relevant perspective. It must be
+noted that this feature only makes sense a controlled situation, that is: user
+modules or macros of unpredictable origin will probably suffer from warnings and
+errors when de mode is set to non zero. In \CONTEXT\ we're okay unless of course
+users redefine instances but there a warning or error is kind of welcome.
+
+\stopsection
+
+\startsection[title=Constants]
+
+It is rather common to store constant values in a register or character
+definition.
+
+\starttyping
+\newcount\MyConstantA \MyConstantA 123
+\newdimen\MyConstantB \MyConstantB 123pt
+\chardef \MyConstantC \MyConstantC 123
+\stoptyping
+
+But in \LUAMETATEX\ we also can do this:
+
+\starttyping
+\integerdef\MyConstantC 456
+\dimendef \MyConstantD 456pt
+\stoptyping
+
+These two are stored as efficient as a register but don't occupy a register slot.
+They can be set as above, need \prm {the} for serializations and are seen as
+valid number or dimension when needed.
+
+Experiments with constant strings made the engine source more complex than I
+wanted so that features was rejected. Of course we can use the prefixes mentioned
+in a previous section.
+
\stopsection
\startsection[title=Nodes]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex
index 917ebfeb86f..9a09f705c10 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex
@@ -140,7 +140,6 @@ For example, here is the character \quote {f} (decimal 102) in the font \type
}
\stoptyping
-
Two very special string indexes can be used also: \type {left_boundary} is a
virtual character whose ligatures and kerns are used to handle word boundary
processing. \type {right_boundary} is similar but not actually used for anything
@@ -269,9 +268,25 @@ third one is a previously defined font that is known to \LUATEX\ as font id~38.
The array index numbers are used by the character command definitions that are
part of each character.
-The \type {commands} array is a hash where each item is another small array,
-with the first entry representing a command and the extra items being the
-parameters to that command. The allowed commands and their arguments are:
+The \type {commands} array is a hash where each item is another small array, with
+the first entry representing a command and the extra items being the parameters
+to that command. The frontend is only interested in the dimensions, ligatures and
+kerns of a font, which is the reason why the \TEX\ engine didn't have to be
+extended when virtual fonts showed up: dealing with it is up to the driver that
+comes after the backend. In \PDFTEX\ and \LUATEX\ that driver is integrated so
+there the backend also deals with virtual fonts. The first block in the next
+table is what the standard mentions. The \type {special} command is indeed
+special because it is an extension container. The mentioned engines only support
+pseudo standards where the content starts with \type {pdf:}. The last block is
+\LUATEX\ specific and will not be found in native fonts. These entries can be
+used in virtual fonts that are constructed in \LUA.
+
+But \unknown\ in \LUAMETATEX\ there is no backend built in but we might assume
+that the one provided deals with these entries. However, a provided backend can
+provide more and that is indeed what happens in \CONTEXT. There, because we no
+longer have compacting (of passed tables) and unpacking (when embedding) of these
+tables going on we stay in the \LUA\ domain. None of the virtual specification is
+ever seen in the engine.
\starttabulate[|l|l|l|p|]
\DB command \BC arguments \BC type \BC description \NC \NR
@@ -279,16 +294,18 @@ parameters to that command. The allowed commands and their arguments are:
\NC \type{font} \NC 1 \NC number \NC select a new font from the local \type {fonts} table \NC \NR
\NC \type{char} \NC 1 \NC number \NC typeset this character number from the current font,
and move right by the character's width \NC \NR
-\NC \type{node} \NC 1 \NC node \NC output this node (list), and move right
- by the width of this list\NC \NR
-\NC \type{slot} \NC 2 \NC 2 numbers \NC a shortcut for the combination of a font and char command\NC \NR
\NC \type{push} \NC 0 \NC \NC save current position\NC \NR
-\NC \type{nop} \NC 0 \NC \NC do nothing \NC \NR
\NC \type{pop} \NC 0 \NC \NC pop position \NC \NR
\NC \type{rule} \NC 2 \NC 2 numbers \NC output a rule $ht*wd$, and move right. \NC \NR
\NC \type{down} \NC 1 \NC number \NC move down on the page \NC \NR
\NC \type{right} \NC 1 \NC number \NC move right on the page \NC \NR
+\HL
\NC \type{special} \NC 1 \NC string \NC output a \prm {special} command \NC \NR
+\HL
+\NC \type{nop} \NC 0 \NC \NC do nothing \NC \NR
+\NC \type{slot} \NC 2 \NC 2 numbers \NC a shortcut for the combination of a font and char command\NC \NR
+\NC \type{node} \NC 1 \NC node \NC output this node (list), and move right
+ by the width of this list\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 {text}, \type {font}, \type {direct} or \type {raw}; if you
have one string only \type {origin} is assumed \NC \NR
@@ -363,10 +380,6 @@ The special can have a \type {pdf:}, \type {pdf:origin:}, \type {pdf:page:},
\type {pdf:direct:} or \type {pdf:raw:} prefix. When you have to concatenate
strings using the \type {pdf} command might be more efficient.
-The fields mentioned above can be found in external fonts. It is good to keep in
-mind that we can extend this model, given that the backend knows what to do with
-it.
-
\stopsection
\startsection[title={Additional \TEX\ commands}]
@@ -392,17 +405,19 @@ expansion takes place inside the argument.
\fontid\font
\stopsyntax
-This primitive expands into a number. It is not a register so there is no need to
-prefix with \prm {number} (and using \prm {the} gives an error). The currently
-used font id is \fontid\font. Here are some more:
+This primitive expands into a number. The currently used font id is
+\number\fontid\font. Here are some more: \footnote {Contrary to \LUATEX\ this is
+now a number so you need to use \type {\number} or \type {\the}. The same is true
+for some other numbers and dimensions that for some reason ended up in the
+serializer that produced a sequence of tokens.}
\starttabulate[|l|c|c|]
\DB style \BC command \BC font id \NC \NR
\TB
-\NC normal \NC \type {\tf} \NC \tf \fontid\font \NC \NR
-\NC bold \NC \type {\bf} \NC \bf \fontid\font \NC \NR
-\NC italic \NC \type {\it} \NC \it \fontid\font \NC \NR
-\NC bold italic \NC \type {\bi} \NC \bi \fontid\font \NC \NR
+\NC normal \NC \type {\tf} \NC \tf \number\fontid\font \NC \NR
+\NC bold \NC \type {\bf} \NC \bf \number\fontid\font \NC \NR
+\NC italic \NC \type {\it} \NC \it \number\fontid\font \NC \NR
+\NC bold italic \NC \type {\bi} \NC \bi \number\fontid\font \NC \NR
\LL
\stoptabulate
@@ -417,29 +432,92 @@ which of course needs to be a valid one.
\stopsubsection
-\startsubsection[title={\lpr {noligs} and \lpr {nokerns}}]
+\startsubsection[title={\lpr {glyphoptions}}]
\topicindex {ligatures+suppress}
\topicindex {kerns+suppress}
+\topicindex {expansion+suppress}
+\topicindex {protrusion+suppress}
-These primitives prohibit ligature and kerning insertion at the time when the
-initial node list is built by \LUATEX's main control loop. You can enable these
-primitives when you want to do node list processing of \quote {characters}, where
-\TEX's normal processing would get in the way.
+In \LUATEX\ the \type {\noligs} and \type {\nokerns} primitives suppress these
+features but in \LUAMETATEX\ these primitives are gone. They are replace by a more
+generic control primitive \lpr {glyphoptions}. This numerical parameter is a
+bitset with the following fields:
-\startsyntax
-\noligs <integer>!crlf
-\nokerns <integer>
-\stopsyntax
+\starttabulate[|l|pl|]
+\DB value \BC effect \NC\NR
+\TB
+\NC \type{0x01} \NC prevent left ligature \NC \NR
+\NC \type{0x02} \NC prevent right ligature \NC \NR
+\NC \type{0x04} \NC block left kern \NC \NR
+\NC \type{0x08} \NC block right kern \NC \NR
+\NC \type{0x10} \NC don't apply expansion \NC \NR
+\NC \type{0x20} \NC don't apply protrusion \NC \NR
+\NC \type{0x40} \NC apply xoffset to width \NC \NR
+\NC \type{0x80} \NC apply yoffset to height and depth \NC \NR
+\LL
+\stoptabulate
-These primitives can also be implemented by overloading the ligature building and
-kerning functions, i.e.\ by assigning dummy functions to their associated
-callbacks. Keep in mind that when you define a font (using \LUA) you can also
-omit the kern and ligature tables, which has the same effect as the above.
+The effects speak for themselves. They provide detailed control over individual
+glyph, this because the current value of this option is stored with glyphs.
\stopsubsection
-\startsubsection[title={\type{\nospaces}}]
+\startsubsection[title={\lpr {glyphxscale}, \lpr {glyphyscale} and \lpr {scaledfontdimen}}]
+
+The two scale parameters control the current scaling. They are traditional \TEX\
+integer parameters that operate independent of each other. The scaling is
+reflected in the dimensions of glyphs as well as in the related font dimensions,
+which means that units like \type {ex} and \type {em} work as expected. If you
+query a font dimensions with \prm {fontdimen} you get the raw value but with \lpr
+{scaledfontdimen} you get the useable value.
+
+\stopsubsection
+
+\startsubsection[title={\lpr {glyphxoffset}, \lpr {glyphyoffset}}]
+
+These two parameters control the horizontal and vertical shift of glyphs with,
+when applied to a stretch of them, the horizontal offset probably being the least
+useful.
+
+\stopsubsection
+
+\startsubsection[title={\lpr {glyph}}]
+
+This command is a variation in \prm {char} that takes keywords:
+
+\starttabulate[|l|p|]
+\DB keyword \BC effect \NC type \NC \NR
+\TB
+\NC \type {xoffset} \NC (virtual) horizontal shift \NC dimension \NC \NR
+\NC \type {yoffset} \NC (virtual) vertical shift \NC dimension \NC \NR
+\NC \type {xscale} \NC horizontal scaling \NC integer \NC \NR
+\NC \type {yscale} \NC vertical scaling \NC integer \NC \NR
+\NC \type {options} \NC glyph options \NC bitset \NC \NR
+\NC \type {font} \NC font \NC identifier \NC \NR
+\NC \type {id} \NC font \NC integer \NC \NR
+\LL
+\stoptabulate
+
+The values default to the currently set values. Here is a \CONTEXT\ example:
+
+\startbuffer
+\ruledhbox{
+ \ruledhbox{\glyph yoffset 1ex options 0 123}
+ \ruledhbox{\glyph xoffset .5em yoffset 1ex options "C0 125}
+ \ruledhbox{baseline\glyphyoffset 1ex \glyphxscale 800 \glyphyscale\glyphxscale raised}
+}
+\stopbuffer
+
+\typebuffer
+
+Visualized:
+
+\getbuffer
+
+\stopsubsection
+
+\startsubsection[title={\lpr{nospaces}}]
\topicindex {spaces+suppress}
@@ -462,7 +540,7 @@ space.
\stopsubsection
-\startsubsection[title={\type{\protrusionboundary}}]
+\startsubsection[title={\lpr{protrusionboundary}}]
\topicindex {protrusion}
\topicindex {boundaries}
@@ -581,13 +659,19 @@ font.current(<number> i)
\stopsubsection
-% \startsubsection[title={Glyph data: \lpr {glyphdata}]
-%
-% This primitive can be used to set an additional glyph property. Of course it's very
-% macro package dependant what is done with that. Consider it an experiment (we had
-% some room left in the glyphs data structure). It's basically an single attribute.
-%
-% \stopsubsection
+\startsubsection[title={Glyph data: \lpr {glyphdata}, \lpr {glyphscript}, \lpr {glyphstate}}]
+
+These primitives can be used to set an additional glyph properties. Of course
+it's very macro package dependant what is done with that. It started with just
+the first one as experiment, simply because we had some room left in the glyph
+data structure. It's basically an single attribute. Then, when we got rid of the
+ligature pointer we could either drop it or use that extra field for some more,
+and because \CONTEXT\ already used the data field, that is what happened. The
+script and state fields are shorts, that is, they run from zero to \type {0xFFFF}
+where we assume that zero means \quote {unset}. Although they can be used for
+whatever purpose their use in \CONTEXT\ is fixed.
+
+\stopsubsection
\stopsection
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex
index 774f3d8d9a1..2339bd34201 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex
@@ -28,42 +28,60 @@ happened in a series of documents, parts of which were published as articles in
user group journals, but all are in the \CONTEXT\ distribution. I did the same
with the development of \LUAMETATEX.
-The \LUAMETATEX\ engine is, as said, a lightweight version of \LUATEX, that for
-now targets \CONTEXT. We will use it for possibly drastic experiments but without
-affecting \LUATEX. As we can easily adapt \CONTEXT\ to support both, no other
-macro package will be harmed when (for instance) interfaces change as part of an
-experiment. Of course, when we consider something to be useful, it can be ported
-back to \LUATEX, but only when there are good reasons for doing so and when no
-compatibility issues are involved. When considering this follow up one
-consideration was that a lean and mean version with an extension mechanism is a
-bit closer to original \TEX. Of course, because we also have new primitives, this
-is not entirely true. The move to \LUA\ already meant that some aspects,
-especially system dependent ones, no longer made sense and therefore had
-consequences for the interface at the system level.
-
-This manual currently has quite a bit of overlap with the \LUATEX\ manual but
-some chapters are removed, others added and the rest has been (and will be
-further) adapted. It also discusses the (main) differences. Some of the new
-primitives or functions that show up in \LUAMETATEX\ might show up in \LUATEX\ at
-some point, others might not, so don't take this manual as reference for \LUATEX
-! For now it is an experimental engine in which we can change things at will but
-with \CONTEXT\ in tandem so that this macro package will keep working.
-
-For \CONTEXT\ users the \LUAMETATEX\ engine will become the default. The
-\CONTEXT\ variant for this engine is tagged \LMTX. The pair can be used in
-production, just as with \LUATEX\ and \MKIV. In fact, most users will probably
-not really notice the difference. In some cases there will be a drop in
+The \LUAMETATEX\ engine is, as said, a follow up on \LUATEX. Just as we have
+\CONTEXT\ \MKII\ for \PDFTEX\ and \XETEX, we have \MKIV\ for \LUATEX. For
+\LUAMETATEX\ we have yet another version of \CONTEXT: \LMTX. By freezing \MKII,
+and at some point freezing \MKIV, we can move on as we like, but we try to remain
+downward compatible where possible, something that the user interface makes
+possible. Although \LUAMETATEX\ can be used for production we can also use it for
+possibly drastic experiments but without affecting \LUATEX. Because we can easily
+adapt \CONTEXT\ to support both, no other macro package will be harmed when (for
+instance) the interface that the engine provides change as part of an experiment
+or cleanup of code. Of course, when we consider something to be useful, it can be
+ported back to \LUATEX, but only when there are good reasons for doing so and
+when no compatibility issues are involved.
+
+By now the code of these two related engines differs a lot so in retrospect it
+makes less sense to waste time on backporting anyway. When considering this
+follow up one consideration was that a lean and mean version with an extension
+mechanism is a bit closer to original \TEX. Of course, because we also have new
+primitives, this is not entirely true. The basic algorithms remain the same but
+code got reshuffled and because we expose internals names of variables and such
+are sometimes changed, something that is noticeable in the token and node
+interfaces. Delegating tasks to \LUA\ already meant that some aspects, especially
+system dependent ones, no longer made sense and therefore had consequences for
+the interface at the system level. In \LUAMETATEX\ more got delegated, like all
+file related operations. The penalty of moving more responsibility to \LUA\ has
+been compensated by (hopefully) harmless optimization of code in the engine and
+some more core functionality.
+
+This manual started as an adaptation of the \LUATEX\ manual and therefore looks
+similar. Some chapters are removed, others were added and the rest has been (and
+will be further) adapted. It also discusses the (main) differences. Some of the
+new primitives or functions that show up in \LUAMETATEX\ might show up in
+\LUATEX\ at some point, but most will be exclusive to \LUAMETATEX, so don't take
+this manual as reference for \LUATEX ! As long as we're experimenting we can
+change things at will but as we keep \CONTEXT\ \LMTX\ synchronized users normally
+won't notice this. Often you can find examples of usage in \CONTEXT\ related
+documents and the source code so that serves a reference too.
+
+For \CONTEXT\ users the \LUAMETATEX\ engine will become the default. As
+mentioned, the \CONTEXT\ variant for this engine is tagged \LMTX. The pair can be
+used in production, just as with \LUATEX\ and \MKIV. In fact, most users will
+probably not really notice the difference. In some cases there will be a drop in
performance, due to more work being delegated to \LUA, but on the average
performance will be better, also due to some changes below the hood of the
-engine.
+engine. Memory consumption is also less. The timeline of development is roughly:
+from 2018 upto 2020 engine development, 2019 upto 2021 the stepwise code split
+between \MKIV\ and \LMTX, while in 2020 we will (mostly) freeze \MKIV\ and \LMTX\
+will be the default.
As this follow up is closely related to \CONTEXT\ development, and because we
expect stock \LUATEX\ to be used outside the \CONTEXT\ proper, there will be no
special mailing list nor coverage (or pollution) on the \LUATEX\ related mailing
lists. We have the \CONTEXT\ mailing lists for that. In due time the source code
-will be part of the regular \CONTEXT\ distribution.
-
-% \testpage[8]
+will be part of the regular \CONTEXT\ distribution so that is then also the
+reference implementation: if needed users can compile the binary themselves.
This manual sometimes refers to \LUATEX, especially when we talk of features
common to both engine, as well as to \LUAMETATEX, when it is more specific to the
@@ -100,43 +118,55 @@ Hans Hagen
\vfilll
-{\bf remark:} \LUAMETATEX\ development is mostly done by Hans Hagen and Alan
-Braslau, who love playing with the three languages involved. And as usual Mojca
-Miklavec make sure all compiles well on the buildbot infrastructure. Testing is
-done by \CONTEXT\ developers and users. Many thanks for their patience!
+{\bf remark:} \LUAMETATEX\ development is mostly done by Hans Hagen and in
+adapting the macros to the new features Wolfgang Schuster, who knows the code
+inside||out is a instrumental. In the initial phase Alan Braslau, who love
+playing with the three languages did extensive testing and compiled for several
+platforms. Later Mojca Miklavec make sure all compiles well on the buildbot
+infrastructure. After the first release more users got involved in testing. Many
+thanks for their patience! The development also triggered upgrading of the wiki
+support infrastructure where Taco Hoekwater and Paul Mazaitis have teamed up. So,
+progress all around.
{\bf remark:} When there are non|-|intrusive features that also make sense in
\LUATEX, these will be applied in the experimental branch first, so that there is
-no interference with the stable release.
+no interference with the stable release. However, given that in the meantime the
+code bases differs a lot, it is unlikely that much will trickle back. This is no
+real problem as there's not much demand for that anyway.
{\bf remark:} Most \CONTEXT\ users seem always willing to keep up with the latest
versions which means that \LMTX\ is tested well. We can therefore safely claim
that end of 2019 the code has become quite stable. There are no complaints about
-performance (on my laptop this manual compiles at 22.5 pps with \LMTX\ versus
-20.7 pps for the \LUATEX\ manual with \MKIV). Probably no one notices it, but
-memory consumption stepwise got reduced too. And \unknown\ the binary is still
-below 3~MegaBytes on all platforms.
+performance (on my 2013 laptop this manual compiles at 24.5 pps with \LMTX\
+versus 20.7 pps for the \LUATEX\ manual with \MKIV). After updating some of the
+\CONTEXT\ code to use recently added features by the end of 2020 I could do more
+than 25.5 pps but don't expect spectacular bumps in performance (I need a new
+machine for that to happen). Probably no one notices it, but memory consumption
+stepwise got reduced too. And \unknown\ the binary is still below 3~MegaBytes on
+all platforms.
\stopchapter
\stopcomponent
-% I'm not that strict with incrementing numbers, but let's occasionally bump
-% the number. Once we're stable it might happen more systematically. For sure
-% I don't want to end up with these redicoulous 0.99999999 kind of numbers.
-%
+% I'm not that strict with incrementing numbers, but let's occasionally bump the
+% number. Once we're stable it might happen more systematically. For sure I don't
+% want to end up with these 0.99999999 kind of numbers.
+
% We started with 2.00.0 and kept that number till November 2019, after Alan
-% Braslau and I did the initial beta release at April 1, 2019. After more than
-% a year working on the code base after the \CONTEXT\ 2019 meeting a state was
-% reached where nothing fundamental got added for a while. When \LUATEX\ needs
-% a patch, I check the \LUAMETATEX\ code base as the same patch might be needed
-% there. On the other hand, we don't need a strict compatibility, so some
-% patched in \LUATEX\ are not applied here.
+% Braslau and I did the initial beta release at April 1, 2019. After more than a
+% year working on the code base after the \CONTEXT\ 2019 meeting a state was
+% reached where nothing fundamental got added for a while. When \LUATEX\ needs a
+% patch, I check the \LUAMETATEX\ code base as the same patch might be needed
+% there. On the other hand, we don't need a strict compatibility, so some patched
+% in \LUATEX\ are not applied here.
+%
+% In November 2019 I started wondering if we should bump the number, just for the
+% sake of showing that there's still some progress. So I decided to bump to 2.01.0
+% then. Just as a reminder for myself: it was the day when I watched Jacob Collier
+% perform \LUA\ (feat. MARO) live on YouTube (of course that is not about the
+% language at all, but still a nice coincidence). Just for the fun of it the number
+% bumped a few more times, just to catch up, so end 2019 we're at 2.03.5.
%
-% In November 2019 I started wondering if we should bump the number, just for
-% the sake of showing that there's still some progress. So I decided to bump to
-% 2.01.0 then. Just as a reminder for myself: it was the day when I watched
-% Jacob Collier perform Lua (feat. MARO) live on YouTube (of course that is not
-% about the language at all, but still a nice coincidence). Just for the fun of
-% it the number bumped a few more times, just to catch up, so end 2019 we're at
-% 2.03.5.
+% Thanks to the patient \CONTEXT\ users we were able to apply the new macro scanner
+% and protection mechanisms that were introduced mid 2020.
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex
index 78d73985174..77c2d93d834 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex
@@ -190,17 +190,17 @@ kerning steps.
The start and end of a sequence of characters is signalled by a \nod {glue}, \nod
{penalty}, \nod {kern} or \nod {boundary} node. But by default also a \nod
-{hlist}, \nod {vlist}, \nod {rule}, \nod {dir}, \nod {whatsit}, \nod {ins}, and
+{hlist}, \nod {vlist}, \nod {rule}, \nod {dir}, \nod {whatsit}, \nod {insert}, and
\nod {adjust} node indicate a start or end. You can omit the last set from the
-test by setting \lpr {hyphenationbounds} to a non|-|zero value:
+test by setting flags in \lpr {hyphenationmode}:
\starttabulate[|c|l|]
-\DB value \BC behaviour \NC \NR
+\DB value \BC behaviour \NC \NR
\TB
-\NC \type{0} \NC not strict \NC \NR
-\NC \type{1} \NC strict start \NC \NR
-\NC \type{2} \NC strict end \NC \NR
-\NC \type{3} \NC strict start and strict end \NC \NR
+\NC \NC not strict \NC \NR
+\NC \type{64} \NC strict start \NC \NR
+\NC \type{128} \NC strict end \NC \NR
+\NC \type{192} \NC strict start and strict end \NC \NR
\LL
\stoptabulate
@@ -210,11 +210,11 @@ The word start is determined as follows:
\DB node \BC behaviour \NC \NR
\TB
\BC boundary \NC yes when wordboundary \NC \NR
-\BC hlist \NC when hyphenationbounds 1 or 3 \NC \NR
-\BC vlist \NC when hyphenationbounds 1 or 3 \NC \NR
-\BC rule \NC when hyphenationbounds 1 or 3 \NC \NR
-\BC dir \NC when hyphenationbounds 1 or 3 \NC \NR
-\BC whatsit \NC when hyphenationbounds 1 or 3 \NC \NR
+\BC hlist \NC when the start bit is set \NC \NR
+\BC vlist \NC when the start bit is set \NC \NR
+\BC rule \NC when the start bit is set \NC \NR
+\BC dir \NC when the start bit is set \NC \NR
+\BC whatsit \NC when the start bit is set \NC \NR
\BC glue \NC yes \NC \NR
\BC math \NC skipped \NC \NR
\BC glyph \NC exhyphenchar (one only) : yes (so no -- ---) \NC \NR
@@ -232,13 +232,13 @@ The word end is determined as follows:
\BC glue \NC yes \NC \NR
\BC penalty \NC yes \NC \NR
\BC kern \NC yes when not italic (for some historic reason) \NC \NR
-\BC hlist \NC when hyphenationbounds 2 or 3 \NC \NR
-\BC vlist \NC when hyphenationbounds 2 or 3 \NC \NR
-\BC rule \NC when hyphenationbounds 2 or 3 \NC \NR
-\BC dir \NC when hyphenationbounds 2 or 3 \NC \NR
-\BC whatsit \NC when hyphenationbounds 2 or 3 \NC \NR
-\BC ins \NC when hyphenationbounds 2 or 3 \NC \NR
-\BC adjust \NC when hyphenationbounds 2 or 3 \NC \NR
+\BC hlist \NC when the end bit is set \NC \NR
+\BC vlist \NC when the end bit is set \NC \NR
+\BC rule \NC when the end bit is set \NC \NR
+\BC dir \NC when the end bit is set \NC \NR
+\BC whatsit \NC when the end bit is set \NC \NR
+\BC ins \NC when the end bit is set \NC \NR
+\BC adjust \NC when the end bit is set \NC \NR
\LL
\stoptabulate
@@ -256,131 +256,80 @@ min values to 1 and make sure that the words hyphenate at each character.
\hbox to 2cm {%
\vtop {%
\hsize 1pt
- \hyphenationbounds#1
+ \advance\hyphenationmode#1\relax
#2
\par}}}
\startplacefigure[reference=hb:1,title={\type{one}}]
\startcombination[4*1]
- {\SomeTest{0}{one}} {\type{0}}
- {\SomeTest{1}{one}} {\type{1}}
- {\SomeTest{2}{one}} {\type{2}}
- {\SomeTest{3}{one}} {\type{3}}
+ {\SomeTest {0}{one}} {\type {0}}
+ {\SomeTest {64}{one}} {\type {64}}
+ {\SomeTest{128}{one}} {\type{128}}
+ {\SomeTest{192}{one}} {\type{192}}
\stopcombination
\stopplacefigure
\startplacefigure[reference=hb:2,title={\type{one\null two}}]
\startcombination[4*1]
- {\SomeTest{0}{one\null two}} {\type{0}}
- {\SomeTest{1}{one\null two}} {\type{1}}
- {\SomeTest{2}{one\null two}} {\type{2}}
- {\SomeTest{3}{one\null two}} {\type{3}}
+ {\SomeTest {0}{one\null two}} {\type {0}}
+ {\SomeTest {64}{one\null two}} {\type {64}}
+ {\SomeTest{128}{one\null two}} {\type{128}}
+ {\SomeTest{192}{one\null two}} {\type{192}}
\stopcombination
\stopplacefigure
\startplacefigure[reference=hb:3,title={\type{\null one\null two}}]
\startcombination[4*1]
- {\SomeTest{0}{\null one\null two}} {\type{0}}
- {\SomeTest{1}{\null one\null two}} {\type{1}}
- {\SomeTest{2}{\null one\null two}} {\type{2}}
- {\SomeTest{3}{\null one\null two}} {\type{3}}
+ {\SomeTest {0}{\null one\null two}} {\type {0}}
+ {\SomeTest {64}{\null one\null two}} {\type {64}}
+ {\SomeTest{128}{\null one\null two}} {\type{128}}
+ {\SomeTest{192}{\null one\null two}} {\type{192}}
\stopcombination
\stopplacefigure
\startplacefigure[reference=hb:4,title={\type{one\null two\null}}]
\startcombination[4*1]
- {\SomeTest{0}{one\null two\null}} {\type{0}}
- {\SomeTest{1}{one\null two\null}} {\type{1}}
- {\SomeTest{2}{one\null two\null}} {\type{2}}
- {\SomeTest{3}{one\null two\null}} {\type{3}}
+ {\SomeTest {0}{one\null two\null}} {\type {0}}
+ {\SomeTest {64}{one\null two\null}} {\type {64}}
+ {\SomeTest{128}{one\null two\null}} {\type{128}}
+ {\SomeTest{192}{one\null two\null}} {\type{192}}
\stopcombination
\stopplacefigure
\startplacefigure[reference=hb:5,title={\type{\null one\null two\null}}]
\startcombination[4*1]
- {\SomeTest{0}{\null one\null two\null}} {\type{0}}
- {\SomeTest{1}{\null one\null two\null}} {\type{1}}
- {\SomeTest{2}{\null one\null two\null}} {\type{2}}
- {\SomeTest{3}{\null one\null two\null}} {\type{3}}
+ {\SomeTest {0}{\null one\null two\null}} {\type {0}}
+ {\SomeTest {64}{\null one\null two\null}} {\type {64}}
+ {\SomeTest{128}{\null one\null two\null}} {\type{128}}
+ {\SomeTest{192}{\null one\null two\null}} {\type{192}}
\stopcombination
\stopplacefigure
-% (Future versions of \LUATEX\ might provide more granularity.)
-
In traditional \TEX\ ligature building and hyphenation are interwoven with the
line break mechanism. In \LUATEX\ these phases are isolated. As a consequence we
deal differently with (a sequence of) explicit hyphens. We already have added
some control over aspects of the hyphenation and yet another one concerns
automatic hyphens (e.g.\ \type {-} characters in the input).
-When \lpr {automatichyphenmode} has a value of 0, a hyphen will be turned into
-an automatic discretionary. The snippets before and after it will not be
-hyphenated. A side effect is that a leading hyphen can lead to a split but one
-will seldom run into that situation. Setting a pre and post character makes this
-more prominent. A value of 1 will prevent this side effect and a value of 2 will
-not turn the hyphen into a discretionary. Experiments with other options, like
-permitting hyphenation of the words on both sides were discarded.
-
-\startbuffer[a]
-before-after \par
-before--after \par
-before---after \par
-\stopbuffer
-
-\startbuffer[b]
--before \par
-after- \par
---before \par
-after-- \par
----before \par
-after--- \par
-\stopbuffer
-
-\startbuffer[c]
-before-after \par
-before--after \par
-before---after \par
-\stopbuffer
-
-\startbuffer[demo]
-\startcombination[nx=4,ny=3,location=top]
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\zerocount \hsize6em \getbuffer[a]}} {A~0~6em}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\zerocount \hsize2pt \getbuffer[a]}} {A~0~2pt}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\plusone \hsize2pt \getbuffer[a]}} {A~1~2pt}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\plustwo \hsize2pt \getbuffer[a]}} {A~2~2pt}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\zerocount \hsize6em \getbuffer[b]}} {B~0~6em}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\zerocount \hsize2pt \getbuffer[b]}} {B~0~2pt}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\plusone \hsize2pt \getbuffer[b]}} {B~1~2pt}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\plustwo \hsize2pt \getbuffer[b]}} {B~2~2pt}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\zerocount \hsize6em \getbuffer[c]}} {C~0~6em}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\zerocount \hsize2pt \getbuffer[c]}} {C~0~2pt}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\plusone \hsize2pt \getbuffer[c]}} {C~1~2pt}
- {\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\plustwo \hsize2pt \getbuffer[c]}} {C~2~2pt}
-\stopcombination
-\stopbuffer
-
-\startplacefigure[reference=automatichyphenmode:1,title={The automatic modes \type {0} (default), \type {1} and \type {2}, with a \prm {hsize}
-of 6em and 2pt (which triggers a linebreak).}]
- \dontcomplain \tt \getbuffer[demo]
-\stopplacefigure
-
-\startplacefigure[reference=automatichyphenmode:2,title={The automatic modes \type {0} (default), \type {1} and \type {2}, with \lpr {preexhyphenchar} and \lpr {postexhyphenchar} set to characters \type {A} and \type {B}.}]
- \postexhyphenchar`A\relax
- \preexhyphenchar `B\relax
- \dontcomplain \tt \getbuffer[demo]
-\stopplacefigure
-
-In \in {figure} [automatichyphenmode:1] \in {and} [automatichyphenmode:2] we show
-what happens with three samples:
-
-Input A: \typebuffer[a]
-Input B: \typebuffer[b]
-Input C: \typebuffer[c]
-
-As with primitive companions of other single character commands, the \prm {-}
-command has a more verbose primitive version in \lpr {explicitdiscretionary}
-and the normally intercepted in the hyphenator character \type {-} (or whatever
-is configured) is available as \lpr {automaticdiscretionary}.
+Hyphenation and discretionary injection is driven by a mode parameter which is
+a bitset made from the following values, some of which we saw in the previous
+examples.
+
+\starttabulate[|l|p|]
+\NC \number \normalhyphenationmodecode \NC honour (normal) \prm{discretionary}'s \NC \NR
+\NC \number \automatichyphenationmodecode \NC turn \type {-} into (automatic) discretionaries \NC \NR
+\NC \number \explicithyphenationmodecode \NC turn \type {\-} into (explicit) discretionaries \NC \NR
+\NC \number \syllablehyphenationmodecode \NC hyphenate (syllable) according to language \NC \NR
+\NC \number \uppercasehyphenationmodecode \NC hyphenate uppercase characters too (replaces \prm {uchyph} \NC \NR
+\NC \number \compoundhyphenationmodecode \NC permit break at an explicit hyphen (border cases) \NC \NR
+\NC \number \strictstarthyphenationmodecode \NC traditional \TEX\ compatibility wrt the start of a word \NC \NR
+\NC \number \strictendhyphenationmodecode \NC traditional \TEX\ compatibility wrt the end of a word \NC \NR
+\NC \number \automaticpenaltyhyphenationmodecode \NC use \lpr {automatichyphenpenalty} \NC \NR
+\NC \number \explicitpenaltyhyphenationmodecode \NC use \lpr {explicithyphenpenalty} \NC \NR
+\NC \number \permitgluehyphenationmodecode \NC turn glue in discretionaries into kerns \NC \NR
+\NC \number \lazyligatureshyphenationmodecode \NC controls how successive explicit discretionaries are handled in base mode \NC \NR
+\NC \number \forcecheckhyphenationmodecode \NC treat all discretionaries equal when breaking lines (in all three passes) \NC \NR
+\stoptabulate
\stopsection
@@ -493,25 +442,10 @@ have been added:
\explicithyphenpenalty
\stoptyping
-The first parameter has the following consequences for automatic discs (the ones
-resulting from an \prm {exhyphenchar}):
-
-\starttabulate[|c|l|l|]
-\DB mode \BC automatic disc \type {-} \BC explicit disc \prm{-} \NC \NR
-\TB
-\NC \type{0} \NC \prm {exhyphenpenalty} \NC \prm {exhyphenpenalty} \NC \NR
-\NC \type{1} \NC \prm {hyphenpenalty} \NC \prm {hyphenpenalty} \NC \NR
-\NC \type{2} \NC \prm {exhyphenpenalty} \NC \prm {hyphenpenalty} \NC \NR
-\NC \type{3} \NC \prm {hyphenpenalty} \NC \prm {exhyphenpenalty} \NC \NR
-\NC \type{4} \NC \lpr {automatichyphenpenalty} \NC \lpr {explicithyphenpenalty} \NC \NR
-\NC \type{5} \NC \prm {exhyphenpenalty} \NC \lpr {explicithyphenpenalty} \NC \NR
-\NC \type{6} \NC \prm {hyphenpenalty} \NC \lpr {explicithyphenpenalty} \NC \NR
-\NC \type{7} \NC \lpr {automatichyphenpenalty} \NC \prm {exhyphenpenalty} \NC \NR
-\NC \type{8} \NC \lpr {automatichyphenpenalty} \NC \prm {hyphenpenalty} \NC \NR
-\LL
-\stoptabulate
-
-other values do what we always did in \LUATEX: insert \prm {exhyphenpenalty}.
+The usage of these penalties is controlled by the \lpr {hyphenationmode} flags
+\number\automaticpenaltyhyphenationmodecode\space and
+\number\explicitpenaltyhyphenationmodecode\space and when these are not set \prm
+{exhyphenpenalty} is used.
\stopsection
@@ -575,7 +509,7 @@ In the last line of the table, you see there is no \prm {discretionary} command
in the value: the command is optional in the \TEX-based input syntax. The
underlying reason for that is that it is conceivable that a whole dictionary of
words is stored as a plain text file and loaded into \LUATEX\ using one of the
-functions in the \LUA\ \type {lang} library. This loading method is quite a bit
+functions in the \LUA\ \type {language} library. This loading method is quite a bit
faster than going through the \TEX\ language primitives, but some (most?) of that
speed gain would be lost if it had to interpret command sequences while doing so.
@@ -666,7 +600,7 @@ of the implementation:
\startitem
Because there is no \quote {trie preparation} stage, language patterns never
become frozen. This means that the primitive \prm {patterns} (and its \LUA\
- counterpart \type {lang.patterns}) can be used at any time, not only in
+ counterpart \type {language.patterns}) can be used at any time, not only in
ini\TEX.
\stopitem
\startitem
@@ -690,7 +624,7 @@ of the implementation:
permits a local overload for explicit \prm {discretionary} commands. The
value current when the hyphenation pass is applied is used. When no callbacks
are used this is compatible with traditional \TEX. When you apply the \LUA\
- \type {lang.hyphenate} function the current values are used.
+ \type {language.hyphenate} function the current values are used.
\stopitem
\startitem
The hyphenation exception dictionary is maintained as key|-|value hash, and
@@ -736,7 +670,7 @@ eventually either the limitation will be removed or perhaps it will become
possible to silently ignore the excess characters (this is what happens in
\TEX82, but there the behaviour cannot be controlled).
-If you are using the \LUA\ function \type {lang.hyphenate}, you should be aware
+If you are using the \LUA\ function \type {language.hyphenate}, you should be aware
that this function expects to receive a list of \quote {character} nodes. It will
not operate properly in the presence of \quote {glyph}, \quote {ligature}, or
\quote {ghost} nodes, nor does it know how to deal with kerning.
@@ -774,113 +708,15 @@ that we provide (which is part of \CONTEXT) distinguishes between base mode
(which essentially is what we describe here and which delegates the task to \TEX)
and node mode (which deals with more complex fonts.
-Let's look at an example. Take the word \type {office}, hyphenated \type
-{of-fice}, using a \quote {normal} font with all the \type {f}-\type {f} and
-\type {f}-\type {i} type ligatures:
-
-\starttabulate[|l|l|]
-\NC initial \NC \type {{o}{f}{f}{i}{c}{e}} \NC\NR
-\NC after hyphenation \NC \type {{o}{f}{{-},{},{}}{f}{i}{c}{e}} \NC\NR
-\NC first ligature stage \NC \type {{o}{{f-},{f},{<ff>}}{i}{c}{e}} \NC\NR
-\NC final result \NC \type {{o}{{f-},{<fi>},{<ffi>}}{c}{e}} \NC\NR
-\stoptabulate
-
-That's bad enough, but let us assume that there is also a hyphenation point
-between the \type {f} and the \type {i}, to create \type {of-f-ice}. Then the
-final result should be:
-
-\starttyping
-{o}{{f-},
- {{f-},
- {i},
- {<fi>}},
- {{<ff>-},
- {i},
- {<ffi>}}}{c}{e}
-\stoptyping
-
-with discretionaries in the post-break text as well as in the replacement text of
-the top-level discretionary that resulted from the first hyphenation point.
-
-Here is that nested solution again, in a different representation:
-
-\testpage[4]
-
-\starttabulate[|l|c|c|c|c|c|c|]
-\DB \BC pre \BC \BC post \BC \BC replace \BC \NC \NR
-\TB
-\NC topdisc \NC \type {f-} \NC (1) \NC sub 1 \NC \NC sub 2 \NC \NC \NR
-\NC sub 1 \NC \type {f-} \NC (2) \NC \type {i} \NC (3) \NC \type {<fi>} \NC (4) \NC \NR
-\NC sub 2 \NC \type {<ff>-} \NC (5) \NC \type {i} \NC (6) \NC \type {<ffi>} \NC (7) \NC \NR
-\LL
-\stoptabulate
-
-When line breaking is choosing its breakpoints, the following fields will
-eventually be selected:
-
-\starttabulate[|l|c|c|]
-\NC \type {of-f-ice} \NC \type {f-} \NC (1) \NC \NR
-\NC \NC \type {f-} \NC (2) \NC \NR
-\NC \NC \type {i} \NC (3) \NC \NR
-\NC \type {of-fice} \NC \type {f-} \NC (1) \NC \NR
-\NC \NC \type {<fi>} \NC (4) \NC \NR
-\NC \type {off-ice} \NC \type {<ff>-} \NC (5) \NC \NR
-\NC \NC \type {i} \NC (6) \NC \NR
-\NC \type {office} \NC \type {<ffi>} \NC (7) \NC \NR
-\stoptabulate
-
-The current solution in \LUATEX\ is not able to handle nested discretionaries,
-but it is in fact smart enough to handle this fictional \type {of-f-ice} example.
-It does so by combining two sequential discretionary nodes as if they were a
-single object (where the second discretionary node is treated as an extension of
-the first node).
-
-One can observe that the \type {of-f-ice} and \type {off-ice} cases both end with
-the same actual post replacement list (\type {i}), and that this would be the
-case even if \type {i} was the first item of a potential following ligature like
-\type {ic}. This allows \LUATEX\ to do away with one of the fields, and thus make
-the whole stuff fit into just two discretionary nodes.
-
-The mapping of the seven list fields to the six fields in this discretionary node
-pair is as follows:
-
-\starttabulate[|l|c|c|]
-\DB field \BC description \NC \NC \NR
-\TB
-\NC \type {disc1.pre} \NC \type {f-} \NC (1) \NC \NR
-\NC \type {disc1.post} \NC \type {<fi>} \NC (4) \NC \NR
-\NC \type {disc1.replace} \NC \type {<ffi>} \NC (7) \NC \NR
-\NC \type {disc2.pre} \NC \type {f-} \NC (2) \NC \NR
-\NC \type {disc2.post} \NC \type {i} \NC (3,6) \NC \NR
-\NC \type {disc2.replace} \NC \type {<ff>-} \NC (5) \NC \NR
-\LL
-\stoptabulate
-
-What is actually generated after ligaturing has been applied is therefore:
-
-\starttyping
-{o}{{f-},
- {<fi>},
- {<ffi>}}
- {{f-},
- {i},
- {<ff>-}}{c}{e}
-\stoptyping
-
-The two discretionaries have different subtypes from a discretionary appearing on
-its own: the first has subtype 4, and the second has subtype 5. The need for
-these special subtypes stems from the fact that not all of the fields appear in
-their \quote {normal} location. The second discretionary especially looks odd,
-with things like the \type {<ff>-} appearing in \type {disc2.replace}. The fact
-that some of the fields have different meanings (and different processing code
-internally) is what makes it necessary to have different subtypes: this enables
-\LUATEX\ to distinguish this sequence of two joined discretionary nodes from the
-case of two standalone discretionaries appearing in a row.
-
-Of course there is still that relationship with fonts: ligatures can be implemented by
-mapping a sequence of glyphs onto one glyph, but also by selective replacement and
-kerning. This means that the above examples are just representing the traditional
-approach.
+In so called base mode, where \TEX\ does the work, the ligature construction
+(normally) goes in small steps. An \type {f} followed by an \type {f} becomes an
+\type {ff} ligatures and that one followed by an \type {i} can become a \type
+{ffi} ligature. The situation can be complicated by hyphenation points between
+these characters. When there are several in a ligature collapsing happens. Flag
+{\tttf "\uchexnumbers {\lazyligatureshyphenationmodecode}} in the \lpr
+{hyphenationmode} variable determines if this happens lazy or greedy, i.e.\ the
+first hyphen wins or the last one does. In practice a \CONTEXT\ user won't have
+to deal with this because most fonts are processed in node mode.
\stopsection
@@ -912,7 +748,7 @@ ligatures are used. Of course kerning also complicates matters here.
\stopsection
-\startsection[title={The \type {lang} library}][library=lang]
+\startsection[title={The \type {language} library}][library=lang]
\subsection {\type {new} and \type {id}}
@@ -925,34 +761,38 @@ This library provides the interface to \LUATEX's structure representing a
language, and the associated functions.
\startfunctioncall
-<language> l = lang.new()
-<language> l = lang.new(<number> id)
+<language> l = language.new()
+<language> l = language.new(<number> id)
\stopfunctioncall
This function creates a new userdata object. An object of type \type {<language>}
-is the first argument to most of the other functions in the \type {lang} library.
-These functions can also be used as if they were object methods, using the colon
-syntax. Without an argument, the next available internal id number will be
-assigned to this object. With argument, an object will be created that links to
-the internal language with that id number.
+is the first argument to most of the other functions in the \type {language}
+library. These functions can also be used as if they were object methods, using
+the colon syntax. Without an argument, the next available internal id number will
+be assigned to this object. With argument, an object will be created that links
+to the internal language with that id number.
\startfunctioncall
-<number> n = lang.id(<language> l)
+<number> n = language.id(<language> l)
\stopfunctioncall
-The number returned is the internal \prm {language} id number this object refers to.
+The number returned is the internal \prm {language} id number this object refers
+to.
\subsection {\type {hyphenation}}
\libindex {hyphenation}
-You can hyphenate a string directly with:
+You can load exceptions with:
\startfunctioncall
-<string> n = lang.hyphenation(<language> l)
-lang.hyphenation(<language> l, <string> n)
+<string> n = language.hyphenation(<language> l)
+language.hyphenation(<language> l, <string> n)
\stopfunctioncall
+When no string is given (the first example) a string with all exceptions is
+returned.
+
\subsection {\type {clear_hyphenation} and \type {clean}}
\libindex {clear_hyphenation}
@@ -963,14 +803,14 @@ new ones. The syntax of the string is explained in~\in {section}
[patternsexceptions].
\startfunctioncall
-lang.clear_hyphenation(<language> l)
+language.clear_hyphenation(<language> l)
\stopfunctioncall
This call clears the exception dictionary (string) for this language.
\startfunctioncall
-<string> n = lang.clean(<language> l, <string> o)
-<string> n = lang.clean(<string> o)
+<string> n = language.clean(<language> l, <string> o)
+<string> n = language.clean(<string> o)
\stopfunctioncall
This function creates a hyphenation key from the supplied hyphenation value. The
@@ -984,8 +824,8 @@ dictionary file, like spell|-|checking.
\libindex {clear_patterns}
\startfunctioncall
-<string> n = lang.patterns(<language> l)
-lang.patterns(<language> l, <string> n)
+<string> n = language.patterns(<language> l)
+language.patterns(<language> l, <string> n)
\stopfunctioncall
This adds additional patterns for this language object, or returns the current
@@ -993,7 +833,7 @@ set. The syntax of this string is explained in \in {section}
[patternsexceptions].
\startfunctioncall
-lang.clear_patterns(<language> l)
+language.clear_patterns(<language> l)
\stopfunctioncall
This can be used to clear the pattern dictionary for a language.
@@ -1006,8 +846,8 @@ This function sets (or gets) the value of the \TEX\ parameter
\type {\hyphenationmin}.
\startfunctioncall
-n = lang.hyphenationmin(<language> l)
-lang.hyphenationmin(<language> l, <number> n)
+n = language.hyphenationmin(<language> l)
+language.hyphenationmin(<language> l, <number> n)
\stopfunctioncall
\subsection {\type {[pre|post][ex|]hyphenchar}}
@@ -1018,11 +858,11 @@ lang.hyphenationmin(<language> l, <number> n)
\libindex {postexhyphenchar}
\startfunctioncall
-<number> n = lang.prehyphenchar(<language> l)
-lang.prehyphenchar(<language> l, <number> n)
+<number> n = language.prehyphenchar(<language> l)
+language.prehyphenchar(<language> l, <number> n)
-<number> n = lang.posthyphenchar(<language> l)
-lang.posthyphenchar(<language> l, <number> n)
+<number> n = language.posthyphenchar(<language> l)
+language.posthyphenchar(<language> l, <number> n)
\stopfunctioncall
These two are used to get or set the \quote {pre|-|break} and \quote
@@ -1030,11 +870,11 @@ These two are used to get or set the \quote {pre|-|break} and \quote
intial values are decimal 45 (hyphen) and decimal~0 (indicating emptiness).
\startfunctioncall
-<number> n = lang.preexhyphenchar(<language> l)
-lang.preexhyphenchar(<language> l, <number> n)
+<number> n = language.preexhyphenchar(<language> l)
+language.preexhyphenchar(<language> l, <number> n)
-<number> n = lang.postexhyphenchar(<language> l)
-lang.postexhyphenchar(<language> l, <number> n)
+<number> n = language.postexhyphenchar(<language> l)
+language.postexhyphenchar(<language> l, <number> n)
\stopfunctioncall
These gets or set the \quote {pre|-|break} and \quote {post|-|break} hyphen
@@ -1051,8 +891,8 @@ The next call inserts hyphenation points (discretionary nodes) in a node list. I
are proper nodes, regardless of possible other errors.
\startfunctioncall
-<boolean> success = lang.hyphenate(<node> head)
-<boolean> success = lang.hyphenate(<node> head, <node> tail)
+<boolean> success = language.hyphenate(<node> head)
+<boolean> success = language.hyphenate(<node> head, <node> tail)
\stopfunctioncall
Hyphenation works only on \quote {characters}, a special subtype of all the glyph
@@ -1068,8 +908,8 @@ more details.
The following two commands can be used to set or query hj codes:
\startfunctioncall
-lang.sethjcode(<language> l, <number> char, <number> usedchar)
-<number> usedchar = lang.gethjcode(<language> l, <number> char)
+language.sethjcode(<language> l, <number> char, <number> usedchar)
+<number> usedchar = language.gethjcode(<language> l, <number> char)
\stopfunctioncall
When you set a hjcode the current sets get initialized unless the set was already
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-lua.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-lua.tex
index a126a95dcea..ed4b269b6fb 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-lua.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-lua.tex
@@ -31,9 +31,10 @@ In this mode, it will set \LUA's \type {arg[0]} to the found script name, pushin
preceding options in negative values and the rest of the command line in the
positive values, just like the \LUA\ interpreter does.
-\LUAMETATEX\ will exit immediately after executing the specified \LUA\ script and is,
-in effect, a somewhat bulky stand alone \LUA\ interpreter with a bunch of extra
-preloaded libraries.
+\LUAMETATEX\ will exit immediately after executing the specified \LUA\ script and
+is, in effect, a somewhat bulky stand alone \LUA\ interpreter with a bunch of
+extra preloaded libraries. But we really want to keep the binary small, if
+possible below the 3MB which is okay for a script engine.
When no argument is given, \LUAMETATEX\ will look for a \LUA\ file with the same
name as the binary and run that one when present. This makes it possible to use
@@ -69,6 +70,20 @@ There are less options than with \LUATEX, because one has to deal with them in
\LUA\ anyway. There are no options to enter a safer mode or control executing
programs. This can easily be achieved with a startup \LUA\ script.
+Next the initialization script is loaded and executed. From within the script,
+the entire command line is available in the \LUA\ table \type {arg}, beginning
+with \type {arg[0]}, containing the name of the executable. As consequence
+warnings about unrecognized options are suppressed.
+
+Command line processing happens very early on. So early, in fact, that none of
+\TEX's initializations have taken place yet. The \LUA\ libraries that don't deal
+with \TEX\ are initialized early.
+
+\LUAMETATEX\ allows some of the command line options to be overridden by reading
+values from the \type {texconfig} table at the end of script execution (see the
+description of the \type {texconfig} table later on in this document for more
+details on which ones exactly).
+
The value to use for \prm {jobname} is decided as follows:
\startitemize
@@ -91,21 +106,7 @@ The value to use for \prm {jobname} is decided as follows:
\stopitem
\stopitemize
-Next the initialization script is loaded and executed. From within the script,
-the entire command line is available in the \LUA\ table \type {arg}, beginning
-with \type {arg[0]}, containing the name of the executable. As consequence
-warnings about unrecognized options are suppressed.
-
-Command line processing happens very early on. So early, in fact, that none of
-\TEX's initializations have taken place yet. The \LUA\ libraries that don't deal
-with \TEX\ are initialized early.
-
-\LUAMETATEX\ allows some of the command line options to be overridden by reading
-values from the \type {texconfig} table at the end of script execution (see the
-description of the \type {texconfig} table later on in this document for more
-details on which ones exactly).
-
-So let's summarize this. The handling of when is called jobname is a bit complex.
+So let's summarize this. The handling of what is called jobname is a bit complex.
There can be explicit names set on the command line but when not set they can be
taken from the \type {texconfig} table.
@@ -117,7 +118,9 @@ taken from the \type {texconfig} table.
These names are initialized according to \type {--luaonly} or the first filename
seen in the list of options. Special treatment of \type {&} and \type {*} as well
-as interactive startup is gone.
+as interactive startup is gone but we still enter \TEX\ via an forced \type {\input}
+into the input buffer. \footnote {This might change at some point into an explicit
+loading triggered via \LUA.}
When we are in \TEX\ mode at some point the engine needs a filename, for instance
for opening a log file. At that moment the set jobname becomes the internal one
@@ -133,6 +136,12 @@ access etc.\ internally uses the current code page but to the user is exposed as
% engine_state .startup_jobname : handles by option parser
% environment_state.input_name : temporary interceptor
+There is an extra options \type{--permitloadlib} that needs to be given when you
+load external libraries via \LUA. Although you could manage this via \LUA\ itself
+in a startup script, the reason for having this as option is the wish for
+security (at some point that became a demand for \LUATEX), so this might give an
+extra feeling of protection.
+
\stopsubsection
\stopsection
@@ -199,8 +208,10 @@ some care you can deal with \UNICODE\ just fine.
There are some more libraries present. These are discussed on a later chapter.
For instance we embed \type {luasocket} but contrary to \LUATEX\ don't embed the
related \LUA\ code. An adapted version of \type {luafilesystem} is also included.
-There is a more extensive math library and there are libraries that deal with
-encryption and compression.
+There are more extensive math libraries and there are libraries that deal with
+encryption and compression. At some point some of these might become so called
+optional libraries (read: the handful that we provide interfaces for but that get
+loaded on demand).
\stopsection
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex
index 7f77bbd6d39..02f5f8c71da 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex
@@ -143,7 +143,8 @@ It is possible to discover the math style that will be used for a formula in an
expandable fashion (while the math list is still being read). To make this
possible, \LUATEX\ adds the new primitive: \lpr {mathstyle}. This is a \quote
{convert command} like e.g. \prm {romannumeral}: its value can only be read,
-not set.
+not set. Beware that contrary to \LUATEX\ this is now a proper number so you need
+to use \type {\number} o r\type {\the} in order to serialize it.
The returned value is between 0 and 7 (in math mode), or $-1$ (all other modes).
For easy testing, the eight math style commands have been altered so that they can
@@ -178,55 +179,55 @@ differ from the used style (second pass). In the case of a math choice used
ungrouped, the chosen style is used after the choice too, unless you group.
\startbuffer[1]
- [a:\mathstyle]\quad
+ [a:\number\mathstyle]\quad
\bgroup
\mathchoice
- {\bf \scriptstyle (x:d :\mathstyle)}
- {\bf \scriptscriptstyle (x:t :\mathstyle)}
- {\bf \scriptscriptstyle (x:s :\mathstyle)}
- {\bf \scriptscriptstyle (x:ss:\mathstyle)}
+ {\bf \scriptstyle (x:d :\number\mathstyle)}
+ {\bf \scriptscriptstyle (x:t :\number\mathstyle)}
+ {\bf \scriptscriptstyle (x:s :\number\mathstyle)}
+ {\bf \scriptscriptstyle (x:ss:\number\mathstyle)}
\egroup
- \quad[b:\mathstyle]\quad
+ \quad[b:\number\mathstyle]\quad
\mathchoice
- {\bf \scriptstyle (y:d :\mathstyle)}
- {\bf \scriptscriptstyle (y:t :\mathstyle)}
- {\bf \scriptscriptstyle (y:s :\mathstyle)}
- {\bf \scriptscriptstyle (y:ss:\mathstyle)}
- \quad[c:\mathstyle]\quad
+ {\bf \scriptstyle (y:d :\number\mathstyle)}
+ {\bf \scriptscriptstyle (y:t :\number\mathstyle)}
+ {\bf \scriptscriptstyle (y:s :\number\mathstyle)}
+ {\bf \scriptscriptstyle (y:ss:\number\mathstyle)}
+ \quad[c:\number\mathstyle]\quad
\bgroup
\mathchoice
- {\bf \scriptstyle (z:d :\mathstyle)}
- {\bf \scriptscriptstyle (z:t :\mathstyle)}
- {\bf \scriptscriptstyle (z:s :\mathstyle)}
- {\bf \scriptscriptstyle (z:ss:\mathstyle)}
+ {\bf \scriptstyle (z:d :\number\mathstyle)}
+ {\bf \scriptscriptstyle (z:t :\number\mathstyle)}
+ {\bf \scriptscriptstyle (z:s :\number\mathstyle)}
+ {\bf \scriptscriptstyle (z:ss:\number\mathstyle)}
\egroup
- \quad[d:\mathstyle]
+ \quad[d:\number\mathstyle]
\stopbuffer
\startbuffer[2]
- [a:\mathstyle]\quad
+ [a:\number\mathstyle]\quad
\begingroup
\mathchoice
- {\bf \scriptstyle (x:d :\mathstyle)}
- {\bf \scriptscriptstyle (x:t :\mathstyle)}
- {\bf \scriptscriptstyle (x:s :\mathstyle)}
- {\bf \scriptscriptstyle (x:ss:\mathstyle)}
+ {\bf \scriptstyle (x:d :\number\mathstyle)}
+ {\bf \scriptscriptstyle (x:t :\number\mathstyle)}
+ {\bf \scriptscriptstyle (x:s :\number\mathstyle)}
+ {\bf \scriptscriptstyle (x:ss:\number\mathstyle)}
\endgroup
- \quad[b:\mathstyle]\quad
+ \quad[b:\number\mathstyle]\quad
\mathchoice
- {\bf \scriptstyle (y:d :\mathstyle)}
- {\bf \scriptscriptstyle (y:t :\mathstyle)}
- {\bf \scriptscriptstyle (y:s :\mathstyle)}
- {\bf \scriptscriptstyle (y:ss:\mathstyle)}
- \quad[c:\mathstyle]\quad
+ {\bf \scriptstyle (y:d :\number\mathstyle)}
+ {\bf \scriptscriptstyle (y:t :\number\mathstyle)}
+ {\bf \scriptscriptstyle (y:s :\number\mathstyle)}
+ {\bf \scriptscriptstyle (y:ss:\number\mathstyle)}
+ \quad[c:\number\mathstyle]\quad
\begingroup
\mathchoice
- {\bf \scriptstyle (z:d :\mathstyle)}
- {\bf \scriptscriptstyle (z:t :\mathstyle)}
- {\bf \scriptscriptstyle (z:s :\mathstyle)}
- {\bf \scriptscriptstyle (z:ss:\mathstyle)}
+ {\bf \scriptstyle (z:d :\number\mathstyle)}
+ {\bf \scriptscriptstyle (z:t :\number\mathstyle)}
+ {\bf \scriptscriptstyle (z:s :\number\mathstyle)}
+ {\bf \scriptscriptstyle (z:ss:\number\mathstyle)}
\endgroup
- \quad[d:\mathstyle]
+ \quad[d:\number\mathstyle]
\stopbuffer
\typebuffer[1]
@@ -423,6 +424,7 @@ has resulted in turning some hard codes properties into parameters.
\NC \lpr {Umathsupsubbottommax} \NC the bottom of the superscript of a combined super- and subscript
be at least as high as this above the baseline \NC \NR
\NC \lpr {Umathsubsupvgap} \NC vertical clearance between super- and subscript \NC \NR
+\NC \lpr {Umathspacebeforescript} \NC additional space added before a super- or subprescript (bonus setting) \NC \NR
\NC \lpr {Umathspaceafterscript} \NC additional space added after a super- or subscript \NC \NR
\NC \lpr {Umathconnectoroverlapmin}\NC minimum overlap between parts in an extensible recipe \NC \NR
\LL
@@ -734,7 +736,7 @@ marked \type {*} in the \TEX book. These will not actually be used as those
combinations of atoms cannot actually happen, but it seemed better not to break
orthogonality. They are initialized to zero.
-\subsection{Local settings}
+\subsection{Local \lpr {frozen} settings with}
Math is processed in two passes. The first pass is needed to intercept for
instance \type {\over}, one of the few \TEX\ commands that actually has a
@@ -750,7 +752,7 @@ front.
\startbuffer
$
- x \Usubscript {-}
+ x \Usubscript {-}
\frozen\Umathsubshiftdown\textstyle 0pt x \Usubscript {0}
{\frozen\Umathsubshiftdown\textstyle 5pt x \Usubscript {5}}
x \Usubscript {0}
@@ -775,7 +777,22 @@ unprocessed math list. The result looks as follows:
\blank \getbuffer \blank
+\subsection{Checking a state with \lpr {ifmathparameter}}
+When you adapt math parameters it might make sense to see if they are set at all.
+When a parameter is unset its value has the maximum dimension value and you might
+for instance mistakenly multiply that value to open up things a bit, which gives
+unexpected side effects. For that reason there is a convenient checker: \lpr
+{ifmathparameter}. This test primitive behaves like an \prm {ifcase}, with:
+
+\starttabulate[|c|l|]
+\DB value \BC meaning \NC \NR
+\TB
+\NC 0 \NC the parameter value is zero \NC \NR
+\NC 1 \NC the parameter is set \NC \NR
+\NC 2 \NC the parameter is unset \NC \NR
+\LL
+\stoptabulate
\subsection{Skips around display math and \lpr {mathdisplayskipmode}}
@@ -788,7 +805,7 @@ to fully control spacing. Therefore \LUATEX\ comes with a new directive: \lpr
{mathdisplayskipmode}. The following values apply:
\starttabulate[|c|l|]
-\DB value \BC meaning \NC \NR
+\DB value \BC meaning \NC \NR
\TB
\NC 0 \NC normal \TEX\ behaviour \NC \NR
\NC 1 \NC always (same as 0) \NC \NR
@@ -1096,7 +1113,34 @@ with in the engine). The full list of flags is given in the next table:
\LL
\stoptabulate
-The effect can depend on the font (and for Cambria one can use for instance \type {"16}).
+The effect can depend on the font (and for Cambria one can use for instance \type
+{"16}).
+
+Sometimes you might want to act upon the size of a delimiter, something that is
+not really possible because of the fact that they are calculated {\em after} most
+has been typeset already. For this we have two keyword: \type {phantom} and
+\type {void}. In both cases the symbol is replaced by an empty rule, in the first
+case all three dimensions are preserved in the last case only the height and depth.
+
+\startbuffer
+\startformula
+ x\mathlimop{\Uvextensible \Udelimiter 5 0 "222B}_1^2 x
+\stopformula
+\vskip-9ex
+\startformula \red
+ x\mathlimop{\Uvextensible phantom \Udelimiter 5 0 "222B}_1^2 x
+\stopformula
+\vskip-9ex
+\startformula \blue
+ x\mathlimop{\Uvextensible void \Udelimiter 5 0 "222B}_1^2 x
+\stopformula
+\stopbuffer
+
+\typebuffer
+
+In typeset form this looks like:
+
+\getbuffer
\subsection[mathacc]{Accent handling with \lpr {Umathaccent}}
@@ -1350,7 +1394,80 @@ For Latin Modern the result looks as follows:
\stoptabulate
\stop
-\subsection {Delimiters: \type{\Uleft}, \prm {Umiddle} and \prm {Uright}}
+The \type {\over} and related primitives have the form:
+
+\starttyping
+{{top}\over{bottom}}
+\stoptyping
+
+For convenience, which also avoids some of the trickery that makes this
+\quote {looking back} possible, the \LUAMETATEX\ also provides this variant:
+
+\starttyping
+\Uover{top}{bottom}
+\stoptyping
+
+The optional arguments are also supported but we have one extra option: \type
+{style}. The style is applied to the numerator and denominator.
+
+\starttyping
+\Uover style \scriptstyle {top} {bottom}
+\stoptyping
+
+The complete list of these commands is: \lpr {Uabove}, \lpr {Uatop}, \lpr
+{Uover}, \lpr {Uabovewithdelims}, \lpr {Uatopwithdelims}, \lpr {Uoverwithdelims},
+\lpr {UUskewed}, \lpr {UUskewedwithdelims}. As with other extensions we use a
+leading \type {U} and because we already had extra skew related primitives we end
+up with a \type {UU} there. This obscurity is not that big an issue because
+normally such primitives are wrapped in a macro. Here are a few examples:
+
+\startbuffer
+$\Uover { 1234} { 5678} $\quad
+$\Uover {\textstyle 1234} {\textstyle 5678} $\quad
+$\Uover {\scriptstyle 1234} {\scriptstyle 5678} $\quad
+$\Uover {\scriptscriptstyle 1234} {\scriptscriptstyle 5678} $\blank
+
+$\Uover {1234} {5678} $\quad
+$\Uover style \textstyle {1234} {5678} $\quad
+$\Uover style \scriptstyle {1234} {5678} $\quad
+$\Uover style \scriptscriptstyle {1234} {5678} $\blank
+\stopbuffer
+
+\typebuffer
+
+These render as: \getbuffer
+
+\subsection {Math styles: \lpr {Ustyle}}
+
+This primitive accepts a style identifier:
+
+\starttyping
+\Ustyle \displaystyle
+\stoptyping
+
+This in itself is not spectacular because it is equivalent to
+
+\starttyping
+\displaystyle
+\stoptyping
+
+Both commands inject a style node and change the current style. However, as in other
+places where \LUAMETATEX\ expects a style you can also pass a number in the range
+zero upto seven (like the ones reported by the primitive \lpr {mathstyle}). So, the
+next few lines give identical results:
+
+\startbuffer
+$\Ustyle0 \number\mathstyle \Ustyle7 \number\mathstyle$
+$\Ustyle\displaystyle \number\mathstyle \Ustyle\crampedscriptscriptstyle \number\mathstyle$
+$ \displaystyle \number\mathstyle \crampedscriptscriptstyle \number\mathstyle$
+\stopbuffer
+
+Like: \inlinebuffer . Values outside the valid range are ignored.
+
+There is an extra option \type {norule} that can be used to suppress the rule while
+keeping the spacing compatible.
+
+\subsection {Delimiters: \type{\Uleft}, \lpr {Umiddle} and \lpr {Uright}}
\topicindex {math+delimiters}
@@ -1430,9 +1547,15 @@ These commands are provided as convenience. Before they come available you could
do the following:
\starttyping
-\def\Umathcharclass{\directlua{tex.print(tex.getmathcode(token.scan_int())[1])}}
-\def\Umathcharfam {\directlua{tex.print(tex.getmathcode(token.scan_int())[2])}}
-\def\Umathcharslot {\directlua{tex.print(tex.getmathcode(token.scan_int())[3])}}
+\def\Umathcharclass{\numexpr
+ \directlua{tex.print(tex.getmathcode(token.scan_int())[1])}
+\relax}
+\def\Umathcharfam{\numexpr
+ \directlua{tex.print(tex.getmathcode(token.scan_int())[2])}
+\relax}
+\def\Umathcharslot{\numexpr
+ \directlua{tex.print(tex.getmathcode(token.scan_int())[3])}
+\relax}
\stoptyping
\subsection {Last lines and \lpr{predisplaygapfactor}}
@@ -1569,6 +1692,7 @@ mode parameter. The default value is~1.
\LL
\stoptabulate
+
\subsection {Less Tracing}
\topicindex {math+tracing}
@@ -1579,6 +1703,79 @@ to limit tracing. Only when \type {tracingassigns} and|/|or \type
\stopsection
+\startsection[title={Experiments}]
+
+There are a couple of experimental features. They will stay but details might
+change, for instance more control over spacing. We just show some examples and
+let your imagination work it out. First we have prescripts:
+
+\subsection {Prescripts with \lpr {Usuperprescript} and {Usubprescript}}
+
+\startbuffer
+\hbox{$
+ {\tf X}^1_2^^3__4 \quad
+ {\tf X}^1 ^^3 \quad
+ {\tf X} _1 __4 \quad
+ {\tf X} ^^3 \quad
+ {\tf X} __4 \quad
+ {\tf X}^^3 __4
+$}
+\stopbuffer
+
+\typebuffer
+
+The question is: are these double super and subscript triggers the way to go?
+Anyway, you need to have them either being active (which in \CONTEXT\ then boils
+down to them being other characters), or say \type {\supmarkmode = 1} to disable
+the normal multiple \type {^} treatment (a value larger than 1 will also disable
+that in text mode).
+
+\blank \getbuffer \blank
+
+The more explicit commands are:
+
+\startbuffer
+\hbox{$
+{\tf X}\Usuperscript{1} \quad
+{\tf X} \Usubscript{2} \quad
+{\tf X}\Usuperscript{1}\Usubscript{2} \quad
+{\tf X}\Usuperscript{1} \Usuperprescript{3} \quad
+{\tf X} \Usubscript{2} \Usubprescript{4}\quad
+{\tf X}\Usuperscript{1}\Usubscript{2}\Usuperprescript{3}\Usubprescript{4}\quad
+{\tf X} \Usuperprescript{3} \quad
+{\tf X} \Usubprescript{4}\quad
+{\tf X} \Usuperprescript{3}\Usubprescript{4}
+$}
+\stopbuffer
+
+\typebuffer
+
+These more verbose triggers can be used to build interfaces:
+
+\blank \getbuffer \blank
+
+\subsection {Prescripts with \lpr {Usuperprescript} and {Usubprescript}}
+
+You can change the class of a math character on the fly:
+
+\startbuffer
+$x\mathopen {!}+123+\mathclose {!}x$
+$x\Umathclass4 ! +123+\Umathclass5 ! x$
+$x ! +123+ ! x$
+$x\mathclose {!}+123+\mathopen {!}x$
+$x\Umathclass5 ! +123+\Umathclass4 ! x$
+\stopbuffer
+
+\typebuffer
+
+Watch how the spacing changes:
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex
index bd918995670..c687a5a46d3 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex
@@ -34,26 +34,28 @@ This creates the \type {mp} instance object. The argument is a hash table that
can have a number of different fields, as follows:
\starttabulate[|l|l|pl|pl|]
-\DB name \BC type \BC description \BC default \NC \NR
+\DB name \BC type \BC description \BC default \NC \NR
\TB
-\NC \type{error_line} \NC number \NC error line width \NC 79 \NC \NR
-\NC \type{print_line} \NC number \NC line length in ps output \NC 100 \NC \NR
-\NC \type{random_seed} \NC number \NC the initial random seed \NC variable \NC \NR
+\NC \type{error_line} \NC number \NC error line width \NC 79 \NC \NR
+\NC \type{print_line} \NC number \NC line length in ps output \NC 100 \NC \NR
+\NC \type{random_seed} \NC number \NC the initial random seed \NC variable \NC \NR
\NC \type{math_mode} \NC string \NC the number system to use:
\type {scaled},
\type {double} or
% \type {binary} or
- \type {decimal} \NC \type {scaled} \NC \NR
+ \type {decimal} \NC \type {scaled} \NC \NR
\NC \type{interaction} \NC string \NC the interaction mode:
\type {batch},
\type {nonstop},
\type {scroll} or
- \type {errorstop} \NC \type {errorstop} \NC \NR
-\NC \type{job_name} \NC string \NC a compatibility value \NC \type {mpout} \NC \NR
-\NC \type{find_file} \NC function \NC a function to find files \NC only local files \NC \NR
-\NC \type{utf8} \NC boolean \NC permit characters in the
+ \type {errorstop} \NC \type {errorstop} \NC \NR
+\NC \type{job_name} \NC string \NC a compatibility value \NC \NC \NR
+\NC \type{find_file} \NC function \NC a function to find files \NC only local files \NC \NR
+\NC \type{utf8_mode} \NC boolean \NC permit characters in the
range 128 upto 255 to be
- part of names \NC \type {false} \NC \NR
+ part of names \NC \type {false} \NC \NR
+\NC \type{text_mode} \NC boolean \NC permit characters 2 and 3
+ as fencing string literals \NC \type {false} \NC \NR
\LL
\stoptabulate
@@ -427,10 +429,6 @@ a bunch of vital characteristics of the used pen (all values are floats):
\LL
\stoptabulate
-\stopsection
-
-\startsection[title=Acessors]
-
\subsection[title={Character size information}]
\libindex{char_width}
@@ -441,13 +439,109 @@ These functions find the size of a glyph in a defined font. The \type {fontname}
is the same name as the argument to \type {infont}; the \type {char} is a glyph
id in the range 0 to 255; the returned \type {w} is in AFM units.
-
\startfunctioncall
<number> w = char_width(mp,<string> fontname, <number> char)
<number> h = char_height(mp,<string> fontname, <number> char)
<number> d = char_depth(mp,<string> fontname, <number> char)
\stopfunctioncall
+\stopsection
+
+\startsection[title=Scanners]
+
+After a relative long period of testing the scanners are now part of the
+interface. That doesn't mean that there will be no changes: depending on the
+needs and experiences details might evolve. The summary below is there
+still preliminary and mostly provided as reminder.
+
+\starttabulate[|l|l|p|]
+\DB scanner \BC argument \BC returns \NC \NR
+\TB
+\NC \type{scan_next} \NC instance, keep \NC token, mode, type \NC \NR
+\NC \type{scan_expression} \NC instance, keep \NC type \NC \NR
+\NC \type{scan_token} \NC instance, keep \NC token, mode, kind \NC \NR
+\NC \type{scan_symbol} \NC instance, keep, expand \NC string \NC \NR
+\NC \type{scan_numeric} \NC instance, type \NC number \NC \NR
+\NC \type{scan_integer} \NC instance, type \NC integer \NC \NR
+\NC \type{scan_boolean} \NC instance, type \NC boolean \NC \NR
+\NC \type{scan_string} \NC instance, type \NC string \NC \NR
+\NC \type{scan_pair} \NC instance, hashed, type \NC table or two numbers \NC \NR
+\NC \type{scan_color} \NC instance, hashed, type \NC table or three numbers \NC \NR
+\NC \type{scan_cmykcolor} \NC instance, hashed, type \NC table or four numbers \NC \NR
+\NC \type{scan_transform} \NC instance, hashed, type \NC table or six numbers \NC \NR
+\NC \type{scan_path} \NC instance, hashed, type \NC table with hashes or arrays \NC \NR
+\NC \type{scan_pen} \NC instance, hashed, type \NC table with hashes or arrays \NC \NR
+\LL
+\stoptabulate
+
+The types and token codes are numbers but they actually depend on the
+implementation (although changes are unlikely). The types of data structures can
+be queried with \type {mplib.gettypes()}:
+
+\dontleavehmode \startluacode
+ local t = mplib.gettypes()
+ for i=0,#t do
+ if i > 0 then
+ context(", ")
+ end
+ context("%i: %s",i,t[i])
+ end
+\stopluacode .
+
+The command codes are available with \type {mplib.getcodes()}:
+
+\dontleavehmode \startluacode
+ local t = mplib.getcodes()
+ for i=0,#t do
+ if i > 0 then
+ context(", ")
+ end
+ context("%i: %s",i,t[i])
+ end
+\stopluacode .
+
+Now, if you really want to use these, keep in mind that the internals of
+\METAPOST\ are not trivial, especially because expression scanning can be
+complex. So you need to experiment a bit. In \CONTEXT\ all is (and will be)
+hidden below an abstraction layer so users are not bothered by all these
+look|-|ahead and push|-|back issues that originate in the way \METAPOST\ scans
+its input.
+
+\stopsection
+
+\startsection[title=Injectors]
+
+It is important to know that piping code into the library is pretty fast and
+efficient. Most processing time relates to memory management, calculations and
+generation of output can not be neglected either. Out of curiousity I added some
+functions that directly push data into the library but the gain is not that
+large. \footnote {The main motivation was checking of huge paths could be
+optimized. The other data structures were then added for completeness.}
+
+\starttabulate[|l|l|]
+\DB scanner \BC argument \NC \NR
+\TB
+\NC \type{inject_numeric} \NC instance, number \NC \NR
+\NC \type{inject_integer} \NC instance, number \NC \NR
+\NC \type{inject_boolean} \NC instance, boolean \NC \NR
+\NC \type{inject_string} \NC instance, string \NC \NR
+\NC \type{inject_pair} \NC instance, (table with) two numbers \NC \NR
+\NC \type{inject_color} \NC instance, (table with) three numbers \NC \NR
+\NC \type{inject_cmykcolor} \NC instance, (table with) four numbers \NC \NR
+\NC \type{inject_transform} \NC instance, (table with) six numbers \NC \NR
+\NC \type{inject_path} \NC instance, table with hashes or arrays, cycle, variant \NC \NR
+\LL
+\stoptabulate
+
+The path injector takes a table with subtables that are either hashed (like the
+path solver) or arrays with two, four or six entries. When the third argument has
+the value \type {true} the path is closed. When the fourth argument is \type
+{true} the path is constructed out of straight lines (as with \type {--}) by
+setting the \type {curl} values to~1 automatically. \footnote {This is all
+experimental so future versions might provide more control.}
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-modifications.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-modifications.tex
index 6448f2b01c1..ac283bafd76 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-modifications.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-modifications.tex
@@ -16,14 +16,15 @@
The first version of \LUATEX, made by Hartmut after we discussed the possibility
of an extension language, only had a few extra primitives and it was largely the
same as \PDFTEX. It was presented to the public in 2005. As part of the Oriental
-\TEX\ project, Taco merged substantial parts of \ALEPH\ into the code and some
-more primitives were added. Then we started more fundamental experiments. After
-many years, when the engine had become more stable, the decision was made to
-clean up the rather hybrid nature of the program. This means that some primitives
-were promoted to core primitives, often with a different name, and that others
-were removed. This also made it possible to start cleaning up the code base. In
-\in {chapter} [enhancements] we discuss some new primitives, here we will cover
-most of the adapted ones.
+\TEX\ project, Taco merged some parts of \ALEPH\ into the code and some more
+primitives were added. Then we started more fundamental experiments. After many
+years, when the engine had become more stable, the decision was made to clean up
+the rather hybrid nature of the program. This means that some primitives were
+promoted to core primitives, often with a different name, and that others were
+removed. This also made it possible to start cleaning up the code base, which
+showed decades of stepwise additions to original \TEX. In \in {chapter}
+[enhancements] we discuss some new primitives, here we will cover most of the
+adapted ones.
During more than a decade stepwise new functionality was added and after 10 years
the more of less stable version 1.0 was presented. But we continued and after
@@ -38,9 +39,18 @@ not|-|so|-|expected changes. These are sometimes a side|-|effect of a new
(conflicting) feature, or, more often than not, a change necessary to clean up
the internal interfaces. These will also be mentioned.
+Again we stress that {\em this is not a \TEX\ manual, nor a tutorial}. If you are
+unfamiliar with \TEX\ first play a little with a macro package, take a look at
+the \TEX\ book, make yourself familiar with the concepts and macro language. That
+will likely take days and not hours. Also, many of the new concepts introduced in
+\LUATEX\ and \LUAMETATEX\ are explained in documents that come with the \CONTEXT\
+distribution, articles and presentations. It doesn't pay of to repeat that here,
+especially not in a time when users often search instead of read from cover to
+cover.
+
\stopsubsection
-\startsubsection[title=Changes from \TEX\ 3.1415926]
+\startsubsection[title=Changes from \TEX\ 3.1415926...]
\topicindex {\TEX}
@@ -50,19 +60,21 @@ most still comes from original Knuthian \TEX. But we divert a bit.
\startitemize
\startitem
- The current code base is written in \CCODE, not \PASCAL. The original \CWEB\
+ The current code base is written in \CCODE, not \PASCAL. The original \WEB\
documentation is kept when possible and not wrapped in tagged comments. As a
consequence instead of one large file plus change files, we now have multiple
- files organized in categories like \type {tex}, \type {luaf}, \type
+ files organized in categories like \type {tex}, \type {lua}, \type
{languages}, \type {fonts}, \type {libraries}, etc. There are some artifacts
of the conversion to \CCODE, but these got (and get) removed stepwise. The
documentation, which actually comes from the mix of engines (via so called
- change files), is kept as much as possible. Of course we want to stay as
- close as possible to the original so that the documentation of the
+ change files), is a mix of what authors of the engines wove into the source,
+ and most is of course from Don Knuths original. In \LUAMETATEX\ we try to
+ stay as close as possible to the original so that the documentation of the
fundamentals behind \TEX\ by Don Knuth still applies. However, because we use
\CCODE, some documentation is a bit off. Also, most global variables are now
- collected in structures, but the original names were kept. There are lots of
- so called macros too.
+ collected in structures, but the original names and level of abstraction were
+ mostly kept. On the other hand, opening up had its impact on the code, so
+ that makes some documentation a bit off too. Adapting that all will take time.
\stopitem
\startitem
@@ -74,14 +86,21 @@ most still comes from original Knuthian \TEX. But we divert a bit.
wherever we like. There are various options to control discretionary
injection and related penalties are now integrated in these nodes. Language
information is now bound to glyphs. The number of languages in \LUAMETATEX\
- is smaller than in \LUATEX.
+ is smaller than in \LUATEX. Control over discretionaries is more granular and
+ now managed by less variables.
\stopitem
\startitem
There is no pool file, all strings are embedded during compilation. This also
removed some memory constraints. We kept token and node memory management
because it is convenient and efficient but parts were reimplemented in order
- to remove some constraints. Token memory management is largely the same.
+ to remove some constraints. Token memory management is largely the same. All
+ the other large memory structures, like those related to nesting, the save
+ stack, input levels, the hash table and table of equivalents, etc. now all
+ start out small and are enlarged when needed, where maxima are controlled in
+ the usual way. In principle the initial memory footprint is smaller while at
+ the same time we can go real large. Because we have wide memory words some
+ data (arrays) used for housekeeping could be reorganized a bit.
\stopitem
\startitem
@@ -126,11 +145,9 @@ most still comes from original Knuthian \TEX. But we divert a bit.
\stopitem
\startitem
- When detailed logging is enabled more detail is output with respect to what
- nodes are involved. This is a side effect of the core nodes having more
- detailed subtype information. The benefit of more detail wins from any wish
- to be byte compatible in the logging. One can always write additional logging
- in \LUA.
+ The math style related primitives can use numbers as well as symbolic names.
+ There is some more (control over) math anyway, which is a side effect of
+ supporting \OPENTYPE\ math.
\stopitem
\stopitemize
@@ -172,10 +189,29 @@ features, but with a few small adaptations.
\stopitem
\startitem
+ Because we have more nodes, conditionals, etc.\ the \ETEX\ status related
+ variables are adapted to \LUAMETATEX: we use different \quote {constants},
+ but that should be no problem because any sane macro package uses
+ abstraction.
+\stopitem
+
+\startitem
+ The \type {\scantokens} primitive is now using the same mechanism as \LUA\
+ print|-|to|-|\TEX\ uses, which simplifies the code. There is a little
+ performance hit but it will not be noticed in \CONTEXT, because we never use
+ this primitive.
+\stopitem
+
+\startitem
Because we don't use change files on top of original \TEX, the integration of
\ETEX\ functionality is bit more natural, code wise.
\stopitem
+\startitem
+ The \prm {readline} primitive has to be implemented in \LUA. This is a side
+ effect of delegating all file \IO.
+\stopitem
+
\stopitemize
\stopsubsection
@@ -230,12 +266,7 @@ don't expect \LUAMETATEX\ to be compatible.
\startitem
When \lpr {adjustspacing} has value~2, hz optimization will be applied to
glyphs and kerns. When the value is~3, only glyphs will be treated. A value
- smaller than~2 disables this feature. With value of~1, font expansion is
- applied after \TEX's normal paragraph breaking routines have broken the
- paragraph into lines. In this case, line breaks are identical to standard
- \TEX\ behavior (as with \PDFTEX). But \unknown\ this is a left|-|over from
- the early days of \PDFTEX\ when this feature was part of a research topic. At
- some point level~1 might be dropped from \LUAMETATEX.
+ smaller than~2 disables this feature.
\stopitem
\startitem
@@ -292,7 +323,8 @@ Here is a summary of inherited functionality:
\startitem
Glues {\it immediately after} direction change commands are not legal
- breakpoints. There is a bit more sanity testing for the direction state.
+ breakpoints. There is a bit more sanity testing for the direction state. This
+ can be configured.
\stopitem
\startitem
@@ -303,7 +335,7 @@ Here is a summary of inherited functionality:
\startitem
There are no direction related primitives for page and body directions. The
paragraph, text and math directions are specified using primitives that
- take a number.
+ take a number. The three letter codes are dropped.
\stopitem
\stopitemize
@@ -334,7 +366,10 @@ The single internal memory heap that traditional \TEX\ used for tokens and nodes
is split into two separate arrays. Each of these will grow dynamically when
needed. Internally a token or node is an index into these arrays. This permits
for an efficient implementation and is also responsible for the performance of
-the core. The original documentation in \TEX\ The Program mostly applies!
+the core. All other data structures are mostly the same but managed dynamically
+too. Because we operate in a 64 bit world, the parallel table of equivalents
+needed for managing levels, is gone. Anyhow, the original documentation in \TEX\
+The Program mostly applies!
\stopsubsection
@@ -352,10 +387,6 @@ assignments don't show up when using the \ETEX\ tracing routines \prm
{tracingassigns} and \prm {tracingrestores} but we don't see that as a real
limitation. It also saves a lot of clutter.
-A side|-|effect of the current implementation is that \prm {global} is now more
-expensive in terms of processing than non|-|global assignments but not many users
-will notice that.
-
The glyph ids within a font are also managed by means of a sparse array as glyph
ids can go up to index $2^{21}-1$ but these are never accessed directly so again
users will not notice this.
@@ -367,26 +398,33 @@ users will not notice this.
\topicindex {csnames}
Single|-|character commands are no longer treated specially in the internals,
-they are stored in the hash just like the multiletter csnames.
+they are stored in the hash just like the multiletter control sequences. This is
+a side effect of going \UNICODE\ and \UTF. Where using 256 slots in an array add
+no burden supporting the whole \UNICODE\ range is a waste of space. Therefore,
+also active characters are internally implemented as a special type of
+multi|-|letter control sequences that uses a prefix that is otherwise impossible
+to obtain.
The code that displays control sequences explicitly checks if the length is one
when it has to decide whether or not to add a trailing space.
-Active characters are internally implemented as a special type of multi|-|letter
-control sequences that uses a prefix that is otherwise impossible to obtain.
-
\stopsubsection
\startsubsection[title=Binary file reading]
\topicindex {files+binary}
-All of the internal code is changed in such a way that if one of the \type
-{read_xxx_file} callbacks is not set, then the file is read by a \CCODE\ function
-using basically the same convention as the callback: a single read into a buffer
-big enough to hold the entire file contents. While this uses more memory than the
-previous code (that mostly used \type {getc} calls), it can be quite a bit faster
-(depending on your \IO\ subsystem). So far we never had issues with this approach.
+All input now goes via \LUA: files loaded with \type {\input} as well as files
+that are opened with \type {\openin}. Actually the later has to be implemented
+in terms of macros and \LUA\ calls. This also means that compared to \LUATEX\
+the internal handling of input has been changed but users won't notice that.
+
+Setting a callback is expected now. Although reading input natively using \type
+{getc} calls is more efficient, we now fetch lines from \LUA, put them in a
+buffer and then pick successive bytes (keep in mind that we read \UTF) from that.
+The performance is quite ok, also because \LUA\ is fast, todays operating systems
+cache, and storage media have become very fast. Also, \TEX\ is spending more time
+messing around with what it has input than actually reading input.
\stopsubsection
@@ -416,12 +454,17 @@ more details anyway.
\startsubsection[title=Logging]
+When detailed logging is enabled more detail is output with respect to what nodes
+are involved. This is a side effect of the core nodes having more detailed
+subtype information. The benefit of more detail wins from any wish to be byte
+compatible in the logging. One can always write additional logging in \LUA.
+
The information that goes into the log file can be different from \LUATEX, and
might even differ a bit more in the future. The main reason is that inside the
engine we have more granularity, which for instance means that we output subtype
-related information when nodes are printed. Of course we could have offered a
-compatibility mode but it serves no purpose. Over time there have been many
-subtle changes to control logs in the \TEX\ ecosystems so another one is
+and attribute related information when nodes are printed. Of course we could have
+offered a compatibility mode but it serves no purpose. Over time there have been
+many subtle changes to control logs in the \TEX\ ecosystems so another one is
bearable.
In a similar fashion, there is a bit different behaviour when \TEX\ expects
@@ -429,7 +472,38 @@ input, which in turn is a side effect of removing the interception of \type {*}
and \type {&} which made for cleaner code (quite a bit had accumulated as side
effect of continuous adaptations in the \TEX\ ecosystems). There was already code
that was never executed, simply as side effect of the way \LUATEX\ initializes
-itself (one needs to enable classes of primitives for instance).
+itself (one needs to enable classes of primitives for instance). Keep in mind
+that over time system dependencies have been handles with \TEX\ change files, the
+\WEBC\ infrastructure, \KPSE\ features, compilation variables and flags, etc. In
+\LUAMETATEX\ we try to minimize all that.
+
+\stopsubsection
+
+\startsubsection[title=Parsing]
+
+Token parsers have been upgraded for the sake of \LUA, \type {\csname} handling
+has been extended, macro definitions can be more flexible so there code was
+adapted, more conditionals also brought some changes. But we build upon the
+(reorganized) \TEX\ foundation so the basics can definitely be recognized.
+
+Because of interfacing in \LUA\ the internal token and node organization has
+been normalized (read: we cannot cheat because all is kind of visible). On
+the one hand this can come with a performance penalty but that is more than
+compensated by extensions, optimized parsers and such. Still the fact that we
+are \UTF\ based (32 bit) makes the machinery slower than the 8~bit original.
+The reworked \LUAMETATEX\ engine is substantially faster than the \LUATEX\
+predecessor.
+
+The handling of conditionals has been adapted so that we can have flatter
+branches (\type {\orelse} cum suis). This again has some consequences for
+parsing. Because parsing alignments is rather interwoven in general parsing and
+expansion the handling of related primitives has been slightly adapted (also for
+the sake of \LUA\ interfacing) and dealing with \type {\noalign} situations is a
+bit more convenient.
+
+This are just a few of the adaptations and most of this happened stepwise with
+testing in the \CONTEXT\ code base. It will be clear that \LUAMETATEX\ is a quite
+different extension to the original. You're warned.
\stopsubsection
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex
index 50356da4211..6773d346d78 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex
@@ -174,12 +174,12 @@ discussed here (yet).
\stopsubsection
-\startsubsection[title={\nod {ins} nodes}]
+\startsubsection[title={\nod {insert} nodes}]
\topicindex {nodes+insertions}
\topicindex {insertions}
-This node relates to the \prm {insert} primitive and support the fields: \showfields{ins}.
+This node relates to the \prm {insert} primitive and support the fields: \showfields{insert}.
\starttabulate[|l|l|p|]
\DB field \BC type \BC explanation \NC \NR
@@ -455,7 +455,7 @@ fields: \showfields {glyph}.
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{char} \NC number \NC the character index in the font \NC \NR
\NC \type{font} \NC number \NC the font identifier \NC \NR
-\NC \type{lang} \NC number \NC the language identifier \NC \NR
+\NC \type{language} \NC number \NC the language identifier \NC \NR
\NC \type{left} \NC number \NC the frozen \type {\lefthyphenmnin} value \NC \NR
\NC \type{right} \NC number \NC the frozen \type {\righthyphenmnin} value \NC \NR
\NC \type{uchyph} \NC boolean \NC the frozen \prm {uchyph} value \NC \NR
@@ -521,19 +521,19 @@ nodes: \showfields {boundary} are the only fields.
\TB
\NC \type{subtype} \NC number \NC \showsubtypes{boundary} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
-\NC \type{value} \NC number \NC values 0--255 are reserved \NC \NR
+\NC \type{data} \NC number \NC values 0--255 are reserved \NC \NR
\LL
\stoptabulate
\stopsubsection
-\startsubsection[title={\nod {local_par} nodes}]
+\startsubsection[title={\nod {par} nodes}]
\topicindex {nodes+paragraphs}
\topicindex {paragraphs}
This node is inserted at the start of a paragraph. You should not mess
-too much with this one. Valid fields are: \showfields {local_par}.
+too much with this one. Valid fields are: \showfields {par}.
\starttabulate[|l|l|p|]
\DB field \BC type \BC explanation \NC \NR
@@ -613,7 +613,7 @@ into a single node type with separate subtypes for differentiation: \showfields
Many object fields in math mode are either simple characters in a specific family
or math lists or node lists: \type {math_char}, \type {math_text_char}, {sub_box}
-and \type {sub_mlist} and \type {delim}. These are endpoints and therefore the
+and \type {sub_mlist} and \type {delimiter}. These are endpoints and therefore the
\type {next} and \type {prev} fields of these these subnodes are unused.
Some of the more elaborate noads have an option field. The values in this bitset
@@ -681,11 +681,11 @@ its internal link structure is correct, otherwise an error is triggered.
\stopsubsubsection
-\startsubsubsection[title={\nod {delim} subnodes}]
+\startsubsubsection[title={\nod {delimiter} subnodes}]
There is a fifth subnode type that is used exclusively for delimiter fields. As
before, the \type {next} and \type {prev} fields are unused, but we do have:
-\showfields {delim}.
+\showfields {delimiter}.
\starttabulate[|l|l|p|]
\DB field \BC type \BC explanation \NC \NR
@@ -854,14 +854,14 @@ renderer and might get adapted in the process.
\starttabulate[|l|l|p|]
\DB field \BC type \BC explanation \NC \NR
\TB
-\NC \type{subtype} \NC number \NC \showsubtypes{fence} \NC \NR
-\NC \type{attr} \NC node \NC list of attributes \NC \NR
-\NC \type{delim} \NC delimiter node \NC delimiter specification \NC \NR
-\NC \type{italic} \NC number \NC italic correction \NC \NR
-\NC \type{height} \NC number \NC required height \NC \NR
-\NC \type{depth} \NC number \NC required depth \NC \NR
-\NC \type{options} \NC number \NC bitset of rendering options \NC \NR
-\NC \type{class} \NC number \NC spacing related class \NC \NR
+\NC \type{subtype} \NC number \NC \showsubtypes{fence} \NC \NR
+\NC \type{attr} \NC node \NC list of attributes \NC \NR
+\NC \type{delimiter} \NC delimiter node \NC delimiter specification \NC \NR
+\NC \type{italic} \NC number \NC italic correction \NC \NR
+\NC \type{height} \NC number \NC required height \NC \NR
+\NC \type{depth} \NC number \NC required depth \NC \NR
+\NC \type{options} \NC number \NC bitset of rendering options \NC \NR
+\NC \type{class} \NC number \NC spacing related class \NC \NR
\LL
\stoptabulate
@@ -1182,12 +1182,9 @@ tail node.
<node> tail = node.slide(<node> n)
\stopfunctioncall
-After some callbacks automatic sliding takes place. This feature can be turned
-off with \type {node.fix_node_lists(false)} but you better make sure then that
-you don't mess up lists. In most cases \TEX\ itself only uses \type {next}
-pointers but your other callbacks might expect proper \type {prev} pointers too.
-Future versions of \LUATEX\ can add more checking but this will not influence
-usage.
+In most cases \TEX\ itself only uses \type {next} pointers but your other
+callbacks might expect proper \type {prev} pointers too. So, when you run into
+issues or are in doubt, apply the slide function before you return the list.
\stopsubsubsection
@@ -1386,16 +1383,18 @@ The \type{traverse_char} iterator loops over the \nod {glyph} nodes in a list.
Only nodes with a subtype less than 256 are seen.
\startfunctioncall
-<node> n, font, char = node.traverse_char(<node> n)
+<direct> n, font, char = node.direct.traverse_char(<direct> n)
\stopfunctioncall
The \type{traverse_glyph} iterator loops over a list and returns the list and
filters all glyphs:
\startfunctioncall
-<node> n, font, char = node.traverse_glyph(<node> n)
+<direct> n, font, char = node.traverse_glyph(<direct> n)
\stopfunctioncall
+These functions are only available for direct nodes.
+
\stopsubsubsection
\startsubsubsection[title={\type {traverse_list}}]
@@ -1405,15 +1404,100 @@ filters all glyphs:
This iterator loops over the \nod {hlist} and \nod {vlist} nodes in a list.
\startfunctioncall
-<node> n, id, subtype, list = node.traverse_list(<node> n)
+<direct> n, id, subtype, list = node.traverse_list(<direct> n)
+\stopfunctioncall
+
+The four return values can save some time compared to fetching these fields but
+in practice you seldom need them all. This function is only available for direct
+nodes.
+
+\stopsubsubsection
+
+\startsubsubsection[title={\type {traverse_content}}]
+
+\libindex {traverse_content}
+
+This iterator loops over nodes that have content: \nod {hlist}, \nod {vlist}, \nod {glue}
+with leaders, \nod {glyphs}, \nod {disc} and \nod {rules} nodes.
+
+\startfunctioncall
+<direct> n, id, subtype[, list|leader] = node.traverse_list(<direct> n)
\stopfunctioncall
The four return values can save some time compared to fetching these fields but
-in practice you seldom need them all. So consider it a (side effect of
-experimental) convenience.
+in practice you seldom need them all. This function is only available for direct
+nodes.
\stopsubsubsection
+\startsubsubsection[title={Reverse traversing}]
+
+The traversers also support backward traversal. An optional extra boolean triggers
+this. Yet another optional boolean will automatically start at the end of the
+given list.
+
+\starttyping
+\setbox0\hbox{1 2 3 4 5}
+
+local l = tex.box[0].list
+for n in node.traverse(l) do
+ print("1>",n)
+end
+for n in node.traverse(l,true) do
+ print("2>",n)
+end
+for n in node.traverse(l,true,true) do
+ print("3>",n)
+end
+for n in node.traverse_id(nodes.nodecodes.glyph,l) do
+ print("4>",n)
+end
+for n in node.traverse_id(nodes.nodecodes.glyph,l,true) do
+ print("5>",n)
+end
+for n in node.traverse_id(nodes.nodecodes.glyph,l,true,true) do
+ print("6>",n)
+end
+\stoptyping
+
+This produces something similar to this (the glyph subtype indicates that it has
+been processed by the font handlers):
+
+\starttyping
+1> <node : nil <= 1112 => 590 : glyph 32768>
+1> <node : 1112 <= 590 => 1120 : glue spaceskip>
+1> <node : 590 <= 1120 => 849 : glyph 32768>
+1> <node : 1120 <= 849 => 1128 : glue spaceskip>
+1> <node : 849 <= 1128 => 880 : glyph 32768>
+1> <node : 1128 <= 880 => 1136 : glue spaceskip>
+1> <node : 880 <= 1136 => 1020 : glyph 32768>
+1> <node : 1136 <= 1020 => 1144 : glue spaceskip>
+1> <node : 1020 <= 1144 => nil : glyph 32768>
+2> <node : nil <= 1112 => 590 : glyph 32768>
+3> <node : 1020 <= 1144 => nil : glyph 32768>
+3> <node : 1136 <= 1020 => 1144 : glue spaceskip>
+3> <node : 880 <= 1136 => 1020 : glyph 32768>
+3> <node : 1128 <= 880 => 1136 : glue spaceskip>
+3> <node : 849 <= 1128 => 880 : glyph 32768>
+3> <node : 1120 <= 849 => 1128 : glue spaceskip>
+3> <node : 590 <= 1120 => 849 : glyph 32768>
+3> <node : 1112 <= 590 => 1120 : glue spaceskip>
+3> <node : nil <= 1112 => 590 : glyph 32768>
+4> <node : nil <= 1112 => 590 : glyph 32768>
+4> <node : 590 <= 1120 => 849 : glyph 32768>
+4> <node : 849 <= 1128 => 880 : glyph 32768>
+4> <node : 880 <= 1136 => 1020 : glyph 32768>
+4> <node : 1020 <= 1144 => nil : glyph 32768>
+5> <node : nil <= 1112 => 590 : glyph 32768>
+6> <node : 1020 <= 1144 => nil : glyph 32768>
+6> <node : 880 <= 1136 => 1020 : glyph 32768>
+6> <node : 849 <= 1128 => 880 : glyph 32768>
+6> <node : 590 <= 1120 => 849 : glyph 32768>
+6> <node : nil <= 1112 => 590 : glyph 32768>
+\stoptyping
+
+\stopsubsection
+
\startsubsubsection[title={\type {find_node}}]
\libindex {find_node}
@@ -1436,8 +1520,8 @@ This helper returns the location of the first match at or after node \type {n}:
\libindex {setglue}
-You can set the properties of a glue in one go. If you pass no values, the glue
-will become a zero glue.
+You can set the five properties of a glue in one go. If a non|-|numeric value is
+passed the property becomes zero.
\startfunctioncall
node.setglue(<node> n)
@@ -2095,6 +2179,16 @@ consistency. You can of course always define additional accessors using \type
{getfield} and \type {setfield} with little overhead. When the second argument of
\type {setattributelist} is \type {true} the current attribute list is assumed.
+The \type {reverse} function reverses a given list. The \type {exchange} function
+swaps two nodes; it takes upto three arguments: a head node, and one or two to be
+swapped nodes. When there is no third argument, it will assume that the node
+following node is to be used. So we have:
+
+\starttyping
+head = node.direct.reverse(head)
+head = node.direct.exchange(head,first,[second])
+\stoptyping
+
In \CONTEXT\ some of the not performance|-|critical userdata variants are
emulated in \LUA\ and not in the engine, so we retain downward compatibility.
@@ -2112,22 +2206,23 @@ emulated in \LUA\ and not in the engine, so we retain downward compatibility.
\TB
\supported {check_discretionaries} \nop \yes \yes
\supported {check_discretionary} \nop \yes \yes
-\supported {copy} \yes \yes \relax
\supported {copy_list} \yes \yes \relax
%supported {copy_only} \nop \yes \relax
+\supported {copy} \yes \yes \relax
\supported {count} \nop \yes \yes
-\supported {current_attr} \yes \yes \relax
+\supported {current_attributes} \yes \yes \relax
\supported {dimensions} \nop \yes \yes
\supported {effective_glue} \nop \yes \yes
\supported {end_of_math} \nop \yes \yes
+\supported {find_attribute_range} \nop \yes \relax
\supported {find_attribute} \nop \yes \yes
-%supported {find_attribute_range} \nop \yes \relax
-%supported {find_node} \nop \yes \relax
+\supported {find_node} \nop \yes \relax
\supported {first_glyph} \nop \yes \yes
\supported {flatten_discretionaries} \nop \yes \yes
\supported {flush_list} \yes \yes \relax
\supported {flush_node} \yes \yes \relax
\supported {free} \yes \yes \relax
+\supported {get_attributes} \nop \yes \relax
\supported {get_attribute} \yes \yes \relax
\supported {get_properties_table} \yes \yes \relax
\supported {get_synctex_fields} \nop \yes \relax
@@ -2135,7 +2230,6 @@ emulated in \LUA\ and not in the engine, so we retain downward compatibility.
\supported {getboth} \nop \yes \relax
\supported {getbox} \nop \yes \relax
\supported {getchar} \nop \yes \relax
-\supported {getstate} \nop \yes \relax
\supported {getdata} \nop \yes \relax
\supported {getdepth} \nop \yes \relax
\supported {getdirection} \nop \yes \relax
@@ -2145,42 +2239,65 @@ emulated in \LUA\ and not in the engine, so we retain downward compatibility.
\supported {getfield} \yes \yes \relax
\supported {getfont} \nop \yes \relax
\supported {getglue} \nop \yes \yes
-%supported {getglyphdata} \nop \yes \relax % experiment
+\supported {getglyphdata} \nop \yes \relax % old experiment
+\supported {getglyphdimensions} \nop \yes \yes
+\supported {getglyphscript} \nop \yes \relax % new experiment
+\supported {getglyphstate} \nop \yes \relax % new experiment
\supported {getheight} \nop \yes \relax
\supported {getid} \nop \yes \relax
+\supported {getindex} \nop \yes \relax
+\supported {getkerndimension} \nop \yes \yes
\supported {getkern} \nop \yes \relax
-\supported {getlang} \nop \yes \relax
+\supported {getlanguage} \nop \yes \relax
\supported {getleader} \nop \yes \relax
\supported {getlist} \nop \yes \relax
\supported {getnext} \nop \yes \relax
\supported {getnormalizedline} \nop \yes \relax
\supported {getnucleus} \nop \yes \relax
\supported {getoffsets} \nop \yes \relax
+\supported {getoptions} \nop \yes \relax
\supported {getorientation} \nop \yes \relax
+\supported {getparstate} \nop \yes \relax
\supported {getpenalty} \nop \yes \relax
\supported {getpost} \nop \yes \relax
-\supported {getpre} \nop \yes \relax
\supported {getprev} \nop \yes \relax
+\supported {getpre} \nop \yes \relax
\supported {getproperty} \yes \yes \relax
\supported {getreplace} \nop \yes \relax
+\supported {getscales} \nop \yes \relax
+\supported {getscript} \nop \yes \relax
\supported {getshift} \nop \yes \relax
-\supported {getsub} \nop \yes \relax
+\supported {getstate} \nop \yes \relax
+\supported {getsubpre} \nop \yes \relax
\supported {getsubtype} \nop \yes \relax
+\supported {getsub} \nop \yes \relax
+\supported {getsuppre} \nop \yes \relax
\supported {getsup} \nop \yes \relax
+\supported {gettotal} \yes \yes \relax
+%supported {getwhatever} \nop \yes \relax % experiment for myself
\supported {getwhd} \nop \yes \relax
\supported {getwidth} \nop \yes \relax
+\supported {getxscale} \nop \yes \relax
+\supported {getxyscale} \nop \yes \relax
+\supported {getyscale} \nop \yes \relax
\supported {has_attribute} \yes \yes \relax
\supported {has_dimensions} \nop \yes \relax
\supported {has_field} \yes \yes \relax
+\supported {has_glyph_option} \nop \yes \yes
\supported {has_glyph} \nop \yes \yes
\supported {hpack} \nop \yes \yes
-%supported {ignore_math_skip} \nop \yes \relax
+\supported {hyphenating} \nop \yes \yes
+\supported {ignore_math_skip} \nop \yes \relax
\supported {insert_after} \yes \yes \relax
\supported {insert_before} \yes \yes \relax
\supported {is_char} \nop \yes \relax
\supported {is_direct} \nop \yes \relax
\supported {is_glyph} \nop \yes \relax
+\supported {is_next_char} \nop \yes \relax
+\supported {is_next_glyph} \nop \yes \relax
\supported {is_node} \yes \yes \relax
+\supported {is_prev_char} \nop \yes \relax
+\supported {is_prev_glyph} \nop \yes \relax
\supported {is_valid} \nop \yes \relax
\supported {is_zero_glue} \nop \yes \yes
\supported {kerning} \nop \yes \yes
@@ -2188,22 +2305,23 @@ emulated in \LUA\ and not in the engine, so we retain downward compatibility.
\supported {length} \nop \yes \yes
\supported {ligaturing} \nop \yes \yes
\supported {make_extensible} \nop \yes \yes
+\supported {migrate} \nop \yes \relax
\supported {mlist_to_hlist} \nop \yes \yes
\supported {naturalwidth} \nop \yes \yes
\supported {new} \yes \yes \relax
-\supported {prepend_prevdepth} \nop \yes \yes
+%supported {prepend_prevdepth} \nop \yes \yes
\supported {protect_glyphs} \nop \yes \yes
\supported {protect_glyph} \nop \yes \yes
\supported {protrusion_skippable} \nop \yes \yes
\supported {rangedimensions} \nop \yes \yes
\supported {remove} \yes \yes \relax
+\supported {set_attributes} \nop \yes \relax
\supported {set_attribute} \yes \yes \relax
\supported {set_synctex_fields} \nop \yes \relax
\supported {setattributelist} \nop \yes \relax
\supported {setboth} \nop \yes \relax
\supported {setbox} \nop \yes \relax
\supported {setchar} \nop \yes \relax
-\supported {setstate} \nop \yes \relax
\supported {setdata} \nop \yes \relax
\supported {setdepth} \nop \yes \relax
\supported {setdirection} \nop \yes \relax
@@ -2213,24 +2331,36 @@ emulated in \LUA\ and not in the engine, so we retain downward compatibility.
\supported {setfield} \yes \yes \relax
\supported {setfont} \nop \yes \relax
\supported {setglue} \yes \yes \relax
-%supported {setglyphdata} \nop \yes \relax % experiment
+\supported {setglyphdata} \nop \yes \relax % old experiment
+\supported {setglyphscript} \nop \yes \relax % new experiment
+\supported {setglyphstate} \nop \yes \relax % new experiment
\supported {setheight} \nop \yes \relax
+\supported {setindex} \nop \yes \relax
\supported {setkern} \nop \yes \relax
-\supported {setlang} \nop \yes \relax
+\supported {setlanguage} \nop \yes \relax
\supported {setleader} \nop \yes \relax
\supported {setlink} \nop \yes \relax
\supported {setlist} \nop \yes \relax
\supported {setnext} \nop \yes \relax
\supported {setnucleus} \nop \yes \relax
\supported {setoffsets} \nop \yes \relax
+\supported {setoptions} \nop \yes \relax
\supported {setorientation} \nop \yes \relax
\supported {setpenalty} \nop \yes \relax
+\supported {setpost} \nop \yes \relax
\supported {setprev} \nop \yes \relax
+\supported {setpre} \nop \yes \relax
\supported {setproperty} \yes \yes \relax
+\supported {setreplace} \nop \yes \relax
+\supported {setscales} \nop \yes \relax
+\supported {setscript} \nop \yes \relax
\supported {setshift} \nop \yes \relax
\supported {setsplit} \nop \yes \relax
-\supported {setsub} \nop \yes \relax
+\supported {setstate} \nop \yes \relax
+\supported {setsubpre} \nop \yes \relax
\supported {setsubtype} \nop \yes \relax
+\supported {setsub} \nop \yes \relax
+\supported {setsuppre} \nop \yes \relax
\supported {setsup} \nop \yes \relax
\supported {setwhd} \nop \yes \relax
\supported {setwidth} \nop \yes \relax
@@ -2241,17 +2371,22 @@ emulated in \LUA\ and not in the engine, so we retain downward compatibility.
\supported {todirect} \nop \yes \relax
\supported {tonode} \nop \yes \relax
\supported {tostring} \yes \nop \relax
-\supported {traverse} \yes \yes \relax
+\supported {total} \nop \yes \relax
+\supported {tovaliddirect} \nop \yes \relax
\supported {traverse_char} \yes \yes \relax
+\supported {traverse_content} \yes \yes \relax
\supported {traverse_glyph} \yes \yes \relax
\supported {traverse_id} \yes \yes \relax
\supported {traverse_list} \yes \yes \relax
+\supported {traverse} \yes \yes \relax
\supported {type} \yes \nop \relax
\supported {unprotect_glyphs} \nop \yes \yes
\supported {unprotect_glyph} \nop \yes \yes
+\supported {unset_attributes} \nop \yes \relax
\supported {unset_attribute} \yes \yes \relax
\supported {usedlist} \nop \yes \yes
\supported {uses_font} \nop \yes \yes
+\supported {vertical_break} \nop \yes \relax
\supported {vpack} \nop \yes \yes
\supported {write} \yes \yes \relax
\LL
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-pdf.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-pdf.tex
index 79653fdf8a2..3412d0820fd 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-pdf.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-pdf.tex
@@ -183,6 +183,16 @@ b = getboolean(<pdfe array|dictionary>,index|key)
n = getname (<pdfe array|dictionary>,index|key)
\stoptyping
+The \type {getstring} function has two extra variants:
+
+\starttyping
+s, h = getstring (<pdfe array|dictionary>,index|key,false)
+s = getstring (<pdfe array|dictionary>,index|key,true)
+\stoptyping
+
+The first call returns the original string plus a boolean indicating if the
+string is hex encoded. The second call returns the unencoded string.
+
\stopsubsection
\startsubsection[title={\type {get[dictionary|array|stream]}}]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-preamble.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-preamble.tex
index 8f1400c9f9c..5a2dae818b1 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-preamble.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-preamble.tex
@@ -10,12 +10,12 @@
\topicindex{boxes}
\topicindex{\LUA}
-This is a reference manual, not a tutorial. This means that we discuss changes
-relative to traditional \TEX\ and also present new functionality. As a
-consequence we will refer to concepts that we assume to be known or that might be
-explained later. Because the \LUATEX\ and \LUAMETATEX\ engines open up \TEX\
-there's suddenly quite some more to explain, especially about the way a (to be)
-typeset stream moves through the machinery. However, discussing all that in
+This is a reference manual and not a tutorial. This means that we discuss changes
+relative to traditional \TEX\ and also present new (or extended) functionality.
+As a consequence we will refer to concepts that we assume to be known or that
+might be explained later. Because the \LUATEX\ and \LUAMETATEX\ engines open up
+\TEX\ there's suddenly quite some more to explain, especially about the way a (to
+be) typeset stream moves through the machinery. However, discussing all that in
detail makes not much sense, because deep knowledge is only relevant for those
who write code not possible with regular \TEX\ and who are already familiar with
these internals (or willing to spend time on figuring it out).
@@ -47,19 +47,21 @@ If you still decide to read on, then it's good to know what nodes are, so we do
quick introduction here. If you input this text:
\starttyping
-Hi There
+Hi There ...
\stoptyping
eventually we will get a linked lists of nodes, which in \ASCII\ art looks like:
\starttyping
-H <=> i <=> [glue] <=> T <=> h <=> e <=> r <=> e
+H <=> i <=> [glue] <=> T <=> h <=> e <=> r <=> e ...
\stoptyping
-When we have a paragraph, we actually get something:
+When we have a paragraph, we actually get something like this, where a \type
+{par} node stores some metadata and is followed by a \type {hlist} flagged as
+indent box:
\starttyping
-[localpar] <=> H <=> i <=> [glue] <=> T <=> h <=> e <=> r <=> e <=> [glue]
+[par] <=> [hlist] <=> H <=> i <=> [glue] <=> T <=> h <=> e <=> r <=> e ...
\stoptyping
Each character becomes a so called glyph node, a record with properties like the
@@ -69,16 +71,27 @@ back to a previous node or next node, given that these exist. Sometimes
multiple characters are represented by one glyphs, so one can also get:
\starttyping
-[localpar] <=> H <=> i <=> [glue] <=> Th <=> e <=> r <=> e <=> [glue]
+[par] <=> [hlist] <=> H <=> i <=> [glue] <=> Th <=> e <=> r <=> e ...
\stoptyping
And maybe some characters get positioned relative to each other, so we might
see:
\starttyping
-[localpar] <=> H <=> [kern] <=> i <=> [glue] <=> Th <=> e <=> r <=> e <=> [glue]
+[par] <=> [hlist] <=> H <=> [kern] <=> i <=> [glue] <=> Th <=> e <=> r <=> e ...
\stoptyping
+Actually, the above representation is one view, because in \LUAMETATEX\ we can
+choose for this:
+
+\starttyping
+[par] <=> [glue] <=> H <=> [kern] <=> i <=> [glue] <=> Th <=> e <=> r <=> e ...
+\stoptyping
+
+where glue (currently fixed) is used instead of an empty hlist (think of a \type
+{\hbox}). Options like this are available because want a certain view on these
+lists from the \LUA\ end and the result being predicable is part of that.
+
It's also good to know beforehand that \TEX\ is basically centered around
creating paragraphs and pages. The par builder takes a list and breaks it into
lines. At some point horizontal blobs are wrapped into vertical ones. Lines are
@@ -96,6 +109,10 @@ means these hooks. The \TEX\ engine itself is pretty well optimized but when you
kick in much \LUA\ code, you will notices that performance drops. Don't blame and
bother the authors with performance issues. In \CONTEXT\ over 50\% of the time
can be spent in \LUA, but so far we didn't get many complaints about efficiency.
+Adding more callbacks makes no sense, also because at some point the performance
+hit gets too large. There are plenty ways to achieve one goals. For that reason:
+take remarks about \LUATEX, features, potential, performance etc.\ with a natural
+grain of salt.
Where plain \TEX\ is basically a basic framework for writing a specific style,
macro packages like \CONTEXT\ and \LATEX\ provide the user a whole lot of
@@ -108,7 +125,7 @@ mess around to much, the engine eventually might bark and quit. It can even
crash, because testing everywhere for what users can do wrong is no real option.
When you read about nodes in the following chapters it's good to keep in mind
-their commands that relate to then. Here are a few:
+what commands relate to them. Here are a few:
\starttabulate[|l|l|p|]
\DB command \BC node \BC explanation \NC \NR
@@ -127,6 +144,12 @@ their commands that relate to then. Here are a few:
\LL
\stoptabulate
+Whatever we feed into \TEX\ at some point becomes a token which is either
+interpreted directly or stored in a linked list. A token is just a number that
+encodes a specific command (operator) and some value (operand) that further
+specifies what that command is supposed to do. In addition to an interface to
+nodes, there is an interface to tokens, as later chapters will demonstrate.
+
Text (interspersed with macros) comes from an input medium. This can be a file,
token list, macro body cq.\ arguments, \ some internal quantity (like a number),
\LUA, etc. Macros get expanded. In the process \TEX\ can enter a group. Inside
@@ -137,23 +160,23 @@ all terms used in the next chapters. Don't worry, they loose their magic once yo
use \TEX\ a lot. You have access to most of the internals and when not, at least
it is possible to query some state we're in or level we're at.
-When we talk about packing it can mean two things. When \TEX\ has consumed some
-tokens that represent text the next can happen. When the text is put into a so
-called \type {\hbox} it (normally) first gets hyphenated, next ligatures are
-build, and finally kerns are added. Each of that stages can be overloaded using
-\LUA\ code. When these three stages are finished, the dimension of the content is
-calculated and the box gets its width, height and depth. What happens with the
-box depends on what macros do with it.
+When we talk about pack(ag)ing it can mean two things. When \TEX\ has consumed
+some tokens that represent text. When the text is put into a so called \type
+{\hbox} it (normally) first gets hyphenated (even in an horizontal list), next
+ligatures are build, and finally kerns are added. Each of these stages can be
+overloaded using \LUA\ code. When these three stages are finished, the dimension
+of the content is calculated and the box gets its width, height and depth. What
+happens with the box depends on what macros do with it.
The other thing that can happen is that the text starts a new paragraph. In that
-case some (directional) information is put in front, indentation is prepended and
-some skip appended at the end. Again the three stages are applied but this time,
-afterwards, the long line is broken into lines and the result is either added to
-the content of a box or to the main vertical list (the running text so to say).
-This is called par building. At some point \TEX\ decides that enough is enough
-and it will trigger the page builder. So, building is another concept we will
-encounter. Another example of a builder is the one that turns an intermediate
-math list into something typeset.
+case some information is stored in a leading \type {par} node. Then indentation
+is appended and the paragraph ends with some glue. Again the three stages are
+applied but this time, afterwards, the long line is broken into lines and the
+result is either added to the content of a box or to the main vertical list (the
+running text so to say). This is called par building. At some point \TEX\ decides
+that enough is enough and it will trigger the page builder. So, building is
+another concept we will encounter. Another example of a builder is the one that
+turns an intermediate math list into something typeset.
Wrapping something in a box is called packing. Adding something to a list is
described in terms of contributing. The more complicated processes are wrapped
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex
index 187bbd85acd..edbf7d32c19 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex
@@ -1,395 +1 @@
-% language=uk
-
-\environment luametatex-style
-
-\startcomponent luametatex-primitives
-
-\startchapter[reference=primitives,title={Primitives aka commands}]
-
-\startsection[title=Introduction]
-
-The starting point of \LUATEX\ is \PDFTEX, which itself contains regular \TEX\
-and \ETEX. Because directional support was needed we also took some code from
-\ALEPH\ (\OMEGA). In a later stage the backend specific commands were isolated in
-its own namespace which resulted in a cleaner code base where the backend code no
-longer was interwoven with the normal frontend primitives. We also promoted some
-generic constructs (like box resources and directions) to core functionality.
-
-Some of the \PDFTEX\ support primitives have been around from the start but when
-\LUA\ integration became better and when a token scanner library was added, not
-all of those made sense as primitives. In previous chapters we already mentioned
-what is gone from the core. Deep down some more has changed but not all is
-reflected at the primitive level. Because there is still a considerable amount of
-new primitives, a summary is given below.
-
-\stopsection
-
-\startsection[title=Languages]
-
-\starttabulate[|||p|]
-\NC \type {automatichyphenmode} \NC integer \NC \NC \NR
-\NC \type {automatichyphenpenalty} \NC integer \NC \NC \NR
-\NC \type {hyphenpenaltymode} \NC integer \NC \NC \NR
-\NC \type {compoundhyphenmode} \NC integer \NC \NC \NR
-\NC \type {exceptionpenalty} \NC integer \NC \NC \NR
-\NC \type {explicithyphenpenalty} \NC integer \NC \NC \NR
-\NC \type {hyphenationbounds} \NC integer \NC \NC \NR
-\NC \type {hjcode} \NC charactercode \NC \NC \NR
-\NC \type {hyphenationmin} \NC charactercode \NC \NC \NR
-\NC \type {postexhyphenchar} \NC charactercode \NC \NC \NR
-\NC \type {posthyphenchar} \NC charactercode \NC \NC \NR
-\NC \type {preexhyphenchar} \NC charactercode \NC \NC \NR
-\NC \type {prehyphenchar} \NC charactercode \NC \NC \NR
-\stoptabulate
-
-\stopsection
-
-\startsection[title=Fonts]
-
-\starttabulate[|||p|]
-\NC \type {tracingfonts} \NC integer \NC \NC \NR
-\NC \type {suppressfontnotfounderror} \NC integer \NC \NC \NR
-\NC \type {setfontid} \NC integer \NC \NC \NR
-\NC \type {fontid} \NC font \NC \NC \NR
-\NC \type {efcode} \NC font charactercode \NC \NC \NR
-\NC \type {lpcode} \NC font charactercode \NC \NC \NR
-\NC \type {rpcode} \NC font charactercode \NC \NC \NR
-\stoptabulate
-
-\stopsection
-
-\startsection[title=Math]
-
-\starttabulate[|||p|]
-\NC \type {matholdmode} \NC integer \NC \NC \NR
-\NC \type {mathstyle} \NC integer \NC \NC \NR
-\NC \type {matheqnogapstep} \NC integer \NC \NC \NR
-\NC \type {Uskewed} \NC \NC \NC \NR
-\NC \type {Uskewedwithdelims} \NC \NC \NC \NR
-\NC \type {Ustartdisplaymath} \NC \NC \NC \NR
-\NC \type {Ustartmath} \NC \NC \NC \NR
-\NC \type {Ustopdisplaymath} \NC \NC \NC \NR
-\NC \type {Ustopmath} \NC \NC \NC \NR
-\NC \type {crampeddisplaystyle} \NC \NC \NC \NR
-\NC \type {crampedtextstyle} \NC \NC \NC \NR
-\NC \type {crampedscriptstyle} \NC \NC \NC \NR
-\NC \type {crampedscriptscriptstyle} \NC \NC \NC \NR
-\NC \type {Umathchardef} \NC \NC \NC \NR
-\NC \type {Umathcharnumdef} \NC \NC \NC \NR
-\NC \type {mathdisplayskipmode} \NC integer \NC \NC \NR
-\NC \type {mathscriptsmode} \NC integer \NC \NC \NR
-\NC \type {mathnolimitsmode} \NC integer \NC \NC \NR
-\NC \type {mathitalicsmode} \NC integer \NC \NC \NR
-\NC \type {mathrulesmode} \NC integer \NC \NC \NR
-\NC \type {mathrulesfam} \NC integer \NC \NC \NR
-\NC \type {mathdelimitersmode} \NC integer \NC \NC \NR
-\NC \type {mathflattenmode} \NC integer \NC \NC \NR
-\NC \type {mathpenaltiesmode} \NC integer \NC \NC \NR
-\NC \type {mathrulethicknessmode} \NC integer \NC \NC \NR
-\NC \type {mathscriptboxmode} \NC integer \NC \NC \NR
-\NC \type {mathscriptcharmode} \NC integer \NC \NC \NR
-\NC \type {mathsurroundmode} \NC integer \NC \NC \NR
-\NC \type {nokerns} \NC integer \NC \NC \NR
-\NC \type {noligs} \NC integer \NC \NC \NR
-\NC \type {prebinoppenalty} \NC integer \NC \NC \NR
-\NC \type {predisplaygapfactor} \NC integer \NC \NC \NR
-\NC \type {prerelpenalty} \NC integer \NC \NC \NR
-\NC \type {Usuperscript} \NC command \NC \NC \NR
-\NC \type {Usubscript} \NC command \NC \NC \NR
-\NC \type {Unosuperscript} \NC command \NC \NC \NR
-\NC \type {Unosubscript} \NC command \NC \NC \NR
-\NC \type {Umathcode} \NC \NC \NC \NR
-\NC \type {Umathcodenum} \NC \NC \NC \NR
-\NC \type {Udelcode} \NC \NC \NC \NR
-\NC \type {Udelcodenum} \NC \NC \NC \NR
-\NC \type {Umathaxis} \NC family dimension \NC \NC \NR
-\NC \type {Umathbinbinspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathbinclosespacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathbininnerspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathbinopenspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathbinopspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathbinordspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathbinpunctspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathbinrelspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathclosebinspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathcloseclosespacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathcloseinnerspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathcloseopenspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathcloseopspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathcloseordspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathclosepunctspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathcloserelspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathconnectoroverlapmin} \NC family dimension \NC \NC \NR
-\NC \type {Umathfractiondelsize} \NC family dimension \NC \NC \NR
-\NC \type {Umathfractiondenomdown} \NC family dimension \NC \NC \NR
-\NC \type {Umathfractiondenomvgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathfractionnumup} \NC family dimension \NC \NC \NR
-\NC \type {Umathfractionnumvgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathfractionrule} \NC family dimension \NC \NC \NR
-\NC \type {Umathinnerbinspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathinnerclosespacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathinnerinnerspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathinneropenspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathinneropspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathinnerordspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathinnerpunctspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathinnerrelspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathlimitabovebgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathlimitabovekern} \NC family dimension \NC \NC \NR
-\NC \type {Umathlimitabovevgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathlimitbelowbgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathlimitbelowkern} \NC family dimension \NC \NC \NR
-\NC \type {Umathlimitbelowvgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathnolimitsubfactor} \NC family dimension \NC \NC \NR
-\NC \type {Umathnolimitsupfactor} \NC family dimension \NC \NC \NR
-\NC \type {Umathopbinspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopclosespacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopenbinspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopenclosespacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopeninnerspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopenopenspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopenopspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopenordspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopenpunctspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopenrelspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathoperatorsize} \NC family dimension \NC \NC \NR
-\NC \type {Umathopinnerspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopopenspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopopspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathopordspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathoppunctspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathoprelspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathordbinspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathordclosespacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathordinnerspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathordopenspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathordopspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathordordspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathordpunctspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathordrelspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathoverbarkern} \NC family dimension \NC \NC \NR
-\NC \type {Umathoverbarrule} \NC family dimension \NC \NC \NR
-\NC \type {Umathoverbarvgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathoverdelimiterbgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathoverdelimitervgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathpunctbinspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathpunctclosespacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathpunctinnerspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathpunctopenspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathpunctopspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathpunctordspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathpunctpunctspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathpunctrelspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathquad} \NC family dimension \NC \NC \NR
-\NC \type {Umathradicaldegreeafter} \NC family dimension \NC \NC \NR
-\NC \type {Umathradicaldegreebefore} \NC family dimension \NC \NC \NR
-\NC \type {Umathradicaldegreeraise} \NC family dimension \NC \NC \NR
-\NC \type {Umathradicalkern} \NC family dimension \NC \NC \NR
-\NC \type {Umathradicalrule} \NC family dimension \NC \NC \NR
-\NC \type {Umathradicalvgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathrelbinspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathrelclosespacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathrelinnerspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathrelopenspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathrelopspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathrelordspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathrelpunctspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathrelrelspacing} \NC family dimension \NC \NC \NR
-\NC \type {Umathskewedfractionhgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathskewedfractionvgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathspaceafterscript} \NC family dimension \NC \NC \NR
-\NC \type {Umathstackdenomdown} \NC family dimension \NC \NC \NR
-\NC \type {Umathstacknumup} \NC family dimension \NC \NC \NR
-\NC \type {Umathstackvgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathsubshiftdown} \NC family dimension \NC \NC \NR
-\NC \type {Umathsubshiftdrop} \NC family dimension \NC \NC \NR
-\NC \type {Umathsubsupshiftdown} \NC family dimension \NC \NC \NR
-\NC \type {Umathsubsupvgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathsubtopmax} \NC family dimension \NC \NC \NR
-\NC \type {Umathsupbottommin} \NC family dimension \NC \NC \NR
-\NC \type {Umathsupshiftdrop} \NC family dimension \NC \NC \NR
-\NC \type {Umathsupshiftup} \NC family dimension \NC \NC \NR
-\NC \type {Umathsupsubbottommax} \NC family dimension \NC \NC \NR
-\NC \type {Umathunderbarkern} \NC family dimension \NC \NC \NR
-\NC \type {Umathunderbarrule} \NC family dimension \NC \NC \NR
-\NC \type {Umathunderbarvgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathunderdelimiterbgap} \NC family dimension \NC \NC \NR
-\NC \type {Umathunderdelimitervgap} \NC family dimension \NC \NC \NR
-\NC \type {Udelimiter} \NC \NC \NC \NR
-\NC \type {Umathaccent} \NC \NC \NC \NR
-\NC \type {Umathchar} \NC \NC \NC \NR
-\NC \type {Umathcharnum} \NC \NC \NC \NR
-\NC \type {Ustack} \NC \NC \NC \NR
-\NC \type {Uradical} \NC \NC \NC \NR
-\NC \type {Uroot} \NC \NC \NC \NR
-\NC \type {Uunderdelimiter} \NC \NC \NC \NR
-\NC \type {Uoverdelimiter} \NC \NC \NC \NR
-\NC \type {Udelimiterunder} \NC \NC \NC \NR
-\NC \type {Udelimiterover} \NC \NC \NC \NR
-\NC \type {Uhextensible} \NC \NC \NC \NR
-\NC \type {Uchar} \NC \NC \NC \NR
-\NC \type {Umathcharclass} \NC \NC \NC \NR
-\NC \type {Umathcharfam} \NC \NC \NC \NR
-\NC \type {Umathcharslot} \NC \NC \NC \NR
-\NC \type {Uleft} \NC \NC \NC \NR
-\NC \type {Umiddle} \NC \NC \NC \NR
-\NC \type {Uright} \NC \NC \NC \NR
-\NC \type {Uvextensible} \NC \NC \NC \NR
-\stoptabulate
-
-\stopsection
-
-\startsection[title=Boxes and directions]
-
-\starttabulate[|||p|]
-\NC \type {pardirection} \NC direction \NC \NC \NR
-\NC \type {textdirection} \NC direction \NC \NC \NR
-\NC \type {mathdirection} \NC direction \NC \NC \NR
-\NC \type {linedirection} \NC direction \NC \NC \NR
-\NC \type {breakafterdirmode} \NC integer \NC \NC \NR
-\NC \type {shapemode} \NC integer \NC \NC \NR
-\NC \type {fixupboxesmode} \NC integer \NC \NC \NR
-\NC \type {boxdirection} \NC box direction \NC \NC \NR
-\NC \type {boxorientation} \NC box orientation \NC rotation over 90, 180, 270 degrees \NC \NR
-\NC \type {boxxoffset} \NC box xoffset \NC leaves dimensions untounched \NC \NR
-\NC \type {boxyoffset} \NC box yoffset \NC leaves dimensions untounched \NC \NR
-\NC \type {boxxmove} \NC box xmove \NC offsets that reflect on dimensions \NC \NR
-\NC \type {boxymove} \NC box ymove \NC offsets that reflect on dimensions \NC \NR
-\NC \type {boxtotal} \NC box ht+dp \NC height plus depth (and when assigned halfs) \NC \NR
-\NC \type {boxattr} \NC box attr value \NC (sets) a specific attribute to a value \NC \NR
-\stoptabulate
-
-\stopsection
-
-\startsection[title=Scanning]
-
-\starttabulate[|||p|]
-\NC \type {aftergrouped} \NC text \NC like aftergroup but for given list \NC \NR
-\NC \type {alignmark} \NC \NC equivalent to hash token \NC \NR
-\NC \type {aligntab} \NC \NC equivalent to tab token \NC \NR
-\NC \type {begincsname} \NC command \NC variant of \type {\csname} that ignores undefined commands \NC \NR
-\NC \type {catcodetable} \NC integer \NC switch to catcode table \NC \NR
-\NC \type {csstring} \NC command \NC the command without preceding escape character \NC \NR
-\NC \type {endlocalcontrol} \NC command \NC switches back to the main control loop \NC \NR
-\NC \type {etoksapp} \NC tokenregister text \NC append expanded text to given tokenregister \NC \NR
-\NC \type {etokspre} \NC tokenregister text \NC prepend expanded text to given tokenregister \NC \NR
-\NC \type {expanded} \NC text \NC expands the given text \NC \NR
-\NC \type {frozen} \NN prefix \NC \NC \NR
-\NC \type {futureexpand} \NN token command command \NC expands second ot third token depending on first match \NC \NR
-\NC \type {futureexpandis} \NN token command command \NC as \type {futureexpand} but also skips pars \NC \NR
-\NC \type {futureexpandisap} \NN token command command \NC same as idem but doesn't push back skipped spaces \NC \NR
-\NC \type {gtoksapp} \NC tokenregister text \NC globally append text to given tokenregister \NC \NR
-\NC \type {gtokspre} \NC tokenregister text \NC globally prepend text to given tokenregister \NC \NR
-\NC \type {ifabsdim} \NC dimension <=> dimension \NC test the absolute value of the given dimension \NC \NR
-\NC \type {ifabsnum} \NC integer <=> integer \NC test the absolute value of the given integer \NC \NR
-\NC \type {ifcondition} \NC command \NC assume the next token is a test (so skip as if) \NC \NR
-\NC \type {ifdimen} \NC possibly a dimension \NC acts like an \type {\ifcase} with 1 for valid and 2 for invalid \NC \NR
-\NC \type {ifincsname} \NC command \NC check if we're inside a csname expansion \NC \NR
-\NC \type {ifnumval} \NC \NC \NC \NR
-\NC \type {ifdimval} \NC \NC \NC \NR
-\NC \type {ifchknum} \NC \NC \NC \NR
-\NC \type {ifchkdim} \NC \NC \NC \NR
-\NC \type {ifcmpnum} \NC \NC \NC \NR
-\NC \type {ifcmpdim} \NC \NC \NC \NR
-\NC \type {ifusercmd} \NC command \NC \NC \NR
-\NC \type {ifprotected} \NC command \NC \NC \NR
-\NC \type {iffrozen} \NC command \NC \NC \NR
-\NC \type {iftok} \NC \NC \NC \NR
-\NC \type {ifcstok} \NC \NC \NC \NR
-\NC \type {internalcodesmode} \NC integer \NC \NC \NR
-%NC \type {ifprimitive} \NC command \NC check if the given command is a primitive \NC \NR
-\NC \type {immediateassigned} \NC command \NC (todo) expand the following assignment now\NC \NR
-\NC \type {immediateassignment} \NC command \NC (todo) expand the following assignment now\NC \NR
-\NC \type {initcatcodetable} \NC integer \NC initialize catcode table \NC \NR
-\NC \type {lastnamedcs} \NC command \NC last found command of \type {\ifcsname} construction \NC \NR
-\NC \type {nospaces} \NC integer \NC don't inject spaces \NC \NR
-%NC \type {primitive} \NC command \NC expands the next primitive equivalent \NC \NR
-\NC \type {orelse} \NC condition \NC \NC \NR
-\NC \type {pxdimen} \NC dimension \NC multiplier for the \type {px} unit \NC \NR
-\NC \type {savecatcodetable} \NC integer \NC save catcode table \NC \NR
-\NC \type {scantextokens} \NC text \NC \type {\scantokens} without file side effects \NC \NR
-\NC \type {suppressifcsnameerror} \NC integer \NC recover from issues in csname testing \NC \NR
-\NC \type {suppresslongerror} \NC integer \NC make \type {\long} a nop \NC \NR
-\NC \type {suppressmathparerror} \NC integer \NC accepts \type {\par} and empty lines in math \NC \NR
-\NC \type {suppressoutererror} \NC integer \NC make \type {\outer} a nop \NC \NR
-\NC \type {suppressprimitiveerror} \NC integer \NC don't report an invalid \type {\primitive} \NC \NR
-\NC \type {toksapp} \NC tokenregister text \NC append text to given tokenregister \NC \NR
-\NC \type {tokspre} \NC tokenregister text \NC prepend text to given tokenregister \NC \NR
-\NC \type {xtoksapp} \NC tokenregister text \NC globally append expanded text to given tokenregister \NC \NR
-\NC \type {xtokspre} \NC tokenregister text \NC globally prepend expanded text to given tokenregister \NC \NR
-% new (some end-of-the-year experiment)
-\NC \type {letfrozen} \NC macro \NC sets the frozen property of a macro \NC \NR
-\NC \type {letprotected} \NC macro \NC sets the protected property of a macro \NC \NR
-\NC \type {unletfrozen} \NC macro \NC unsets the frozen property of a macro \NC \NR
-\NC \type {unletprotected} \NC macro \NC unsets the protected property of a macro \NC \NR
-\stoptabulate
-
-\stopsection
-
-\startsection[title=Typesetting]
-
-\starttabulate[|||p|]
-\NC \type {protrudechars} \NC integer \NC \NC \NR
-\NC \type {localbrokenpenalty} \NC integer \NC \NC \NR
-\NC \type {localinterlinepenalty} \NC integer \NC \NC \NR
-\NC \type {adjustspacing} \NC integer \NC \NC \NR
-\NC \type {boundary} \NC command \NC \NC \NR
-\NC \type {noboundary} \NC command \NC \NC \NR
-\NC \type {protrusionboundary} \NC command \NC \NC \NR
-\NC \type {wordboundary} \NC command \NC \NC \NR
-\NC \type {nohrule} \NC command \NC \NC \NR
-\NC \type {novrule} \NC command \NC \NC \NR
-\NC \type {insertht} \NC number \NC \NC \NR
-\NC \type {quitvmode} \NC command \NC \NC \NR
-\NC \type {leftmarginkern} \NC dimension \NC \NC \NR
-\NC \type {rightmarginkern} \NC dimension \NC \NC \NR
-\NC \type {localleftbox} \NC box \NC \NC \NR
-\NC \type {localrightbox} \NC box \NC \NC \NR
-\NC \type {gleaders} \NC command \NC \NC \NR
-\stoptabulate
-
-\stopsection
-
-\startsection[title=\LUA]
-
-\starttabulate[|||p|]
-\NC \type {luacopyinputnodes} \NC integer \NC \NC \NR
-\NC \type {luadef} \NC \NC \NC \NR
-\NC \type {luabytecodecall} \NC \NC \NC \NR
-\NC \type {luafunctioncall} \NC \NC \NC \NR
-\NC \type {latelua} \NC \NC \NC \NR
-\NC \type {lateluafunction} \NC \NC \NC \NR
-\NC \type {luabytecode} \NC \NC \NC \NR
-\NC \type {luaescapestring} \NC \NC \NC \NR
-\NC \type {luafunction} \NC \NC \NC \NR
-\stoptabulate
-
-\stopsection
-
-\startsection[title=Management]
-
-\starttabulate[|||p|]
-\NC \type {outputbox} \NC integer \NC \NC \NR
-\NC \type {clearmarks} \NC \NC \NC \NR
-\NC \type {attribute} \NC \NC \NC \NR
-\NC \type {glet} \NC \NC \NC \NR
-\NC \type {letcharcode} \NC \NC \NC \NR
-\NC \type {attributedef} \NC \NC \NC \NR
-\stoptabulate
-
-\stopsection
-
-\startsection[title=Miscellaneous]
-
-\starttabulate[|||p|]
-\NC \type {luatexversion} \NC \NC \NC \NR
-\NC \type {formatname} \NC \NC \NC \NR
-\NC \type {luatexbanner} \NC \NC \NC \NR
-\NC \type {luatexrevision} \NC \NC \NC \NR
-\stoptabulate
-
-\stopsection
-
-\stopchapter
-
-\stopcomponent
+\starttext \ctxlua {table.save(tex.jobname .. '.lua',tex.primitives())} \stoptext \ No newline at end of file
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-style.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-style.tex
index 3f4b0ad2183..1b4a8d5a1c7 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-style.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-style.tex
@@ -115,11 +115,11 @@
\stopluacode
-\unexpanded\def\showfields #1{\ctxlua{document.functions.showfields("#1")}}
-\unexpanded\def\showid #1{\ctxlua{document.functions.showid("#1")}}
-\unexpanded\def\showsubtypes#1{\ctxlua{document.functions.showsubtypes("#1")}}
-\unexpanded\def\showvalues #1{\ctxlua{document.functions.showvalues(node.values("#1"))}}
-\unexpanded\def\showtypes {\ctxlua{document.functions.showvalues(node.types())}}
+\protected\def\showfields #1{\ctxlua{document.functions.showfields("#1")}}
+\protected\def\showid #1{\ctxlua{document.functions.showid("#1")}}
+\protected\def\showsubtypes#1{\ctxlua{document.functions.showsubtypes("#1")}}
+\protected\def\showvalues #1{\ctxlua{document.functions.showvalues(node.values("#1"))}}
+\protected\def\showtypes {\ctxlua{document.functions.showvalues(node.types())}}
\definecolor[blue] [b=.5]
@@ -130,11 +130,13 @@
%definecolor[othercolor][r=.5,g=.5]
\definecolor[maincolor] [b=.5]
+\definecolor[mooncolor] [b=.5]
\definecolor[keptcolor] [b=.5]
-\definecolor[othercolor][s=.5]
+%\efinecolor[othercolor][s=.5]
+\definecolor[othercolor][r=.5,g=.5]
\writestatus{luametatex manual}{}
-\writestatus{luametatex manual}{defining lucodaot} \usebodyfont [lucidaot]
+\writestatus{luametatex manual}{defining lucidaot} \usebodyfont [lucidaot]
\writestatus{luametatex manual}{defining pagella} \usebodyfont [pagella]
\writestatus{luametatex manual}{defining cambria} \usebodyfont [cambria]
\writestatus{luametatex manual}{defining modern} \usebodyfont [modern]
@@ -195,10 +197,11 @@
\startMPdefinitions
- color luaplanetcolor ; luaplanetcolor := \MPcolor{maincolor} ;
- color luaholecolor ; luaholecolor := white ;
+ string luaplanetcolor ; luaplanetcolor := "maincolor" ;
+ string luamooncolor ; luaplanetcolor := "mooncolor" ;
+ string luaholecolor ; luaholecolor := "white" ;
+ string luaorbitcolor ; luaorbitcolor := "darkgray" ;
numeric luaextraangle ; luaextraangle := 0 ;
- numeric luaorbitfactor ; luaorbitfactor := .25 ;
vardef lualogo = image (
@@ -213,10 +216,10 @@
draw fullcircle rotated 40.5 scaled (1+r)
dashed evenly scaled p
withpen pencircle scaled (p/2)
- withcolor (luaorbitfactor * luaholecolor) ;
+ withcolor luaorbitcolor ;
fill fullcircle scaled r shifted (d+1/8,d+1/8)
rotated - luaextraangle
- withcolor luaplanetcolor ;
+ withcolor luamooncolor ;
fill fullcircle scaled r shifted (d-1/8,d-1/8)
withcolor luaholecolor ;
luaorbitfactor := .25 ;
@@ -229,7 +232,8 @@
fill Page withcolor \MPcolor{othercolor} ;
- luaorbitfactor := 1 ;
+ luaorbitcolor := "white" ;
+ luamooncolor := "maincolor" ;
picture p ; p := lualogo ysized (5*\measure{paperheight}/10) ;
draw p
@@ -251,9 +255,11 @@
% \stoptexdefinition
\startuseMPgraphic{luanumber}
- % luaextraangle := \luaextraangle;
- luaextraangle := if (LastPageNumber < 10) : 10 else : (RealPageNumber / LastPageNumber) * 360 fi;
- luaorbitfactor := 0.25 ;
+ % luaextraangle := \luaextraangle;
+ luaextraangle := if (LastPageNumber < 10) : 10 else : (RealPageNumber / LastPageNumber) * 360 fi;
+ luaorbitcolor := "darkgray" ;
+ luamooncolor := "othercolor" ;
+ % luamooncolor := "maincolor" ;
picture p ; p := lualogo ;
setbounds p to boundingbox fullcircle ;
draw p ysized 1cm ;
@@ -314,13 +320,13 @@
{\strut\useMPgraphic{luanumber}}
\stopsetups
-\unexpanded\def\nonterminal#1>{\mathematics{\langle\hbox{\rm #1}\rangle}}
+\protected\def\nonterminal#1>{\mathematics{\langle\hbox{\rm #1}\rangle}}
% taco's brainwave -) .. todo: create a typing variant so that we can avoid the !crlf
\newcatcodetable\syntaxcodetable
-\unexpanded\def\makesyntaxcodetable
+\protected\def\makesyntaxcodetable
{\begingroup
\catcode`\<=13 \catcode`\|=12
\catcode`\!= 0 \catcode`\\=12
@@ -329,11 +335,11 @@
\makesyntaxcodetable
-\unexpanded\def\startsyntax {\begingroup\catcodetable\syntaxcodetable \dostartsyntax}
-\unexpanded\def\syntax {\begingroup\catcodetable\syntaxcodetable \dosyntax}
+\protected\def\startsyntax {\begingroup\catcodetable\syntaxcodetable \dostartsyntax}
+\protected\def\syntax {\begingroup\catcodetable\syntaxcodetable \dosyntax}
\let\stopsyntax \relax
-\unexpanded\def\syntaxenvbody#1%
+\protected\def\syntaxenvbody#1%
{\par
\tt
\startnarrower
@@ -342,7 +348,7 @@
\stopnarrower
\par}
-\unexpanded\def\syntaxbody#1%
+\protected\def\syntaxbody#1%
{\begingroup
% \maincolor
\tt #1%
@@ -427,13 +433,13 @@
\defineregister[nodeindex]
\defineregister[libraryindex]
-\unexpanded\def\lpr#1{\doifmode{*bodypart}{\primitiveindex[#1]{\bf\tex {#1}}}\tex {#1}}
-\unexpanded\def\prm#1{\doifmode{*bodypart}{\primitiveindex[#1]{\tex {#1}}}\tex {#1}}
-\unexpanded\def\orm#1{\doifmode{*bodypart}{\primitiveindex[#1]{\tex {#1}}}\tex {#1}}
-\unexpanded\def\cbk#1{\doifmode{*bodypart}{\callbackindex [#1]{\type {#1}}}\type{#1}}
-\unexpanded\def\nod#1{\doifmode{*bodypart}{\nodeindex [#1]{\bf\type{#1}}}\type{#1}}
-\unexpanded\def\whs#1{\doifmode{*bodypart}{\nodeindex [#1]{\type {#1}}}\type{#1}}
-\unexpanded\def\noa#1{\doifmode{*bodypart}{\nodeindex [#1]{\type {#1}}}\type{#1}}
+\protected\def\lpr#1{\doifmode{*bodypart}{\primitiveindex[#1]{\bf\tex {#1}}}\tex {#1}}
+\protected\def\prm#1{\doifmode{*bodypart}{\primitiveindex[#1]{\tex {#1}}}\tex {#1}}
+\protected\def\orm#1{\doifmode{*bodypart}{\primitiveindex[#1]{\tex {#1}}}\tex {#1}}
+\protected\def\cbk#1{\doifmode{*bodypart}{\callbackindex [#1]{\type {#1}}}\type{#1}}
+\protected\def\nod#1{\doifmode{*bodypart}{\nodeindex [#1]{\bf\type{#1}}}\type{#1}}
+\protected\def\whs#1{\doifmode{*bodypart}{\nodeindex [#1]{\type {#1}}}\type{#1}}
+\protected\def\noa#1{\doifmode{*bodypart}{\nodeindex [#1]{\type {#1}}}\type{#1}}
\hyphenation{sub-nodes}
@@ -457,14 +463,14 @@
[2]
[textstyle=\tttf]
-\unexpanded\def\lib #1{\doifmode{*bodypart}{\expanded{\libraryindex{\currentlibraryindex+#1}}}\type{\currentlibraryindex.#1}}
-\unexpanded\def\libindex#1{\doifmode{*bodypart}{\expanded{\libraryindex{\currentlibraryindex+#1}}}}
-\unexpanded\def\libidx#1#2{\doifmode{*bodypart}{\expanded{\libraryindex{#1+#2}}\type{#1.#2}}}
-\unexpanded\def\lix #1#2{\doifmode{*bodypart}{\expanded{\libraryindex{#1+#2}}}}
+\protected\def\lib #1{\doifmode{*bodypart}{\expanded{\libraryindex{\currentlibraryindex+#1}}}\type{\currentlibraryindex.#1}}
+\protected\def\libindex#1{\doifmode{*bodypart}{\expanded{\libraryindex{\currentlibraryindex+#1}}}}
+\protected\def\libidx#1#2{\doifmode{*bodypart}{\expanded{\libraryindex{#1+#2}}\type{#1.#2}}}
+\protected\def\lix #1#2{\doifmode{*bodypart}{\expanded{\libraryindex{#1+#2}}}}
% \setstructurepageregister[][keys:1=,entries:1=]
-\unexpanded\def\inlineluavalue#1%
+\protected\def\inlineluavalue#1%
{{\maincolor \ctxlua {
local t = #1
if type(t) == "table" then
@@ -475,4 +481,74 @@
context.typ(t)
}}}
+% Common:
+
+% Added December 9 2020 after being energized by Becca Stevens's Slow Burn music
+% video: interesting what comes out of top musicians working remote.
+
+\startluacode
+local list = token.getprimitives()
+
+-- redo this:
+
+function document.showprimitives(tag)
+ local t = tex.extraprimitives(tag)
+ table.sort(t)
+ for i=1,#t do
+ local v = t[i]
+ if v ~= ' ' and v ~= "/" and v ~= "-" then
+ context.type(v)
+ context.space()
+ end
+ end
+end
+
+-- inspect(tokens.commands)
+
+function document.filteredprimitives(cmd)
+ local t = { }
+ local c = tokens.commands[cmd]
+ for i=1,#list do
+ local l = list[i]
+ if l[1] == c then
+ t[#t+1] = l[3]
+ end
+ end
+ table.sort(t)
+ for i=1,#t do
+ if i > 1 then
+ context(", ")
+ elseif i == #t then
+ context(" and ")
+ end
+ context.typ(t[i])
+ end
+end
+
+function document.allprimitives()
+ local c = tokens.commands
+ local o = tex.getprimitiveorigins()
+ table.sort(list, function(a,b)
+ return a[3] < b[3]
+ end)
+ context.starttabulate { "|T|T|Tc|T|" }
+ context.DB() context("primitive")
+ context.BC() context("command code")
+ context.BC() context("char code")
+ context.BC() context("origin")
+ context.NC() context.NR()
+ context.TB()
+ for i=1,#list do
+ local l = list[i]
+ context.NC() context.tex(l[3])
+ context.NC() context(c[l[1]])
+ context.NC() context(l[2])
+ context.NC() context(o[l[4]])
+ context.NC() context.NR()
+ end
+ context.LL()
+ context.stoptabulate()
+end
+\stopluacode
+
\stopenvironment
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex
index 737f3b96081..503bbfd8293 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex
@@ -4,6 +4,16 @@
\startcomponent luametatex-tex
+% { "getbytecode", lualib_get_bytecode },
+% { "setbytecode", lualib_set_bytecode },
+% { "callbytecode", lualib_call_bytecode },
+% { "getfunctionstable", lualib_get_functions_table },
+% { "getstartupfile", lualib_get_startupfile },
+% { "getversion", lualib_get_version },
+% { "setexitcode", lualib_set_exitcode },
+% { NULL, NULL },
+
+
\startchapter[reference=tex,title={The \TEX\ related libraries}]
\startsection[title={The \type {lua} library}][library=lua]
@@ -11,21 +21,28 @@
\startsubsection[title={Version information}]
\topicindex{libraries+\type{lua}}
-\topicindex{version}
-\topicindex{startupfile}
+\topicindex{getversion}
+\topicindex{getstartupfile}
+
+\libindex{getversion}
+\libindex{getstartupfile}
+
+This version of the used \LUA\ interpreter (currently {\tttf \cldcontext
+{lua.getversion()}}) can be queried with:
-\libindex{version}
-\libindex{startupfile}
+\starttyping
+<string> v = lua.getversion()
+\stoptyping
-This library contains two read|-|only items:
+The name of used startup file, if at all, is returned by:
\starttyping
-<string> v = lua.version
-<string> s = lua.startupfile
+<string> s = lua.getstartupfile()
\stoptyping
-This returns the \LUA\ version identifier string. The value currently is
-\directlua {tex.print(lua.version)}.
+For this document the reported value is:
+
+\blank {\ttx \cldcontext {lua.getstartupfile()}} \blank
\stopsubsection
@@ -60,6 +77,7 @@ This preallocates 100 hash entries and 5000 index entries. The \type
\libindex{bytecode}
\libindex{setbytecode}
\libindex{getbytecode}
+\libindex{callbytecode}
\LUA\ registers can be used to store \LUA\ code chunks. The accepted values for
assignments are functions and \type {nil}. Likewise, the retrieved value is
@@ -67,7 +85,7 @@ either a function or \type {nil}.
\starttyping
lua.bytecode[<number> n] = <function> f
-lua.bytecode[<number> n]()
+<function> f = lua.bytecode[<number> n] % -- f()
\stoptyping
The contents of the \type {lua.bytecode} array is stored inside the format file
@@ -75,8 +93,8 @@ as actual \LUA\ bytecode, so it can also be used to preload \LUA\ code. The
function must not contain any upvalues. The associated function calls are:
\startfunctioncall
-<function> f = lua.getbytecode(<number> n)
lua.setbytecode(<number> n, <function> f)
+<function> f = lua.getbytecode(<number> n)
\stopfunctioncall
Note: Since a \LUA\ file loaded using \type {loadfile(filename)} is essentially
@@ -84,14 +102,14 @@ an anonymous function, a complete file can be stored in a bytecode register like
this:
\startfunctioncall
-lua.bytecode[n] = loadfile(filename)
+lua.setbytecode(n,loadfile(filename))
\stopfunctioncall
Now all definitions (functions, variables) contained in the file can be
created by executing this bytecode register:
\startfunctioncall
-lua.bytecode[n]()
+lua.callbytecode(n)
\stopfunctioncall
Note that the path of the file is stored in the \LUA\ bytecode to be used in
@@ -102,30 +120,6 @@ mind when preloading files into a bytecode register in \INITEX.
\stopsubsection
-\startsubsection[title={Chunk name registers}]
-
-\libindex{name}
-\libindex{setluaname}
-\libindex{getluaname}
-
-There is an array of 65536 (0--65535) potential chunk names for use with the
-\prm {directlua} and \lpr {latelua} primitives.
-
-\startfunctioncall
-lua.name[<number> n] = <string> s
-<string> s = lua.name[<number> n]
-\stopfunctioncall
-
-If you want to unset a \LUA\ name, you can assign \type {nil} to it. The function
-accessors are:
-
-\startfunctioncall
-lua.setluaname(<string> s,<number> n)
-<string> s = lua.getluaname(<number> n)
-\stopfunctioncall
-
-\stopsubsection
-
\startsubsection[title={Introspection}]
\libindex{getstacktop}
@@ -166,96 +160,100 @@ and values as a table.
<table> info = status.list()
\stopfunctioncall
-The keys in the table are the known items, the value is the current value. Almost
-all of the values in \type {status} are fetched through a metatable at run|-|time
-whenever they are accessed, so you cannot use \type {pairs} on \type {status},
-but you {\it can\/} use \type {pairs} on \type {info}, of course. If you do not
-need the full list, you can also ask for a single item by using its name as an
-index into \type {status}. The current list is:
+The keys in the table are the known items, the value is the current value. There are
+toplevel items and items that are tables with subentries. The current list is:
-\starttabulate[|l|p|]
-\DB key \BC explanation \NC \NR
+\startluacode
+ local list = status.list()
+
+ context.starttabulate { "|Tw(10em)|Tp|" }
+ context.DB()
+ context("toplevel statistics")
+ context.BC()
+ context.NC()
+ context.NR()
+ context.TB()
+ for k, v in table.sortedhash(list) do
+ if type(v) ~= "table" then
+ context.NC()
+ context(k)
+ context.NC()
+ context(tostring(v))
+ context.NC()
+ context.NR()
+ end
+ end
+ context.LL()
+ context.stoptabulate()
+
+ for k, v in table.sortedhash(list) do
+ if type(v) == "table" then
+ context.starttabulate { "|Tw(10em)|Tp|" }
+ context.DB()
+ context(k ..".*")
+ context.BC()
+ context.NC()
+ context.NR()
+ context.TB()
+ for k, v in table.sortedhash(v) do
+ context.NC()
+ context(k)
+ context.NC()
+ context(v == "" and "unset" or tostring(v))
+ context.NC()
+ context.NR()
+ end
+ context.LL()
+ context.stoptabulate()
+ end
+ end
+\stopluacode
+
+There are also getters for the subtables. The whole repertoire of functions in
+the \type {status} table is: {\tttf \cldcontext {table . concat ( table .
+sortedkeys (status), ", ")}}. The error and warning messages can be wiped with
+the \type {resetmessages} function. The states in subtables relate to memory
+management and are mostly there for development purposes.
+
+The \type {getconstants} query gives back a table with all kind of internal
+quantities and again these are only relevant for diagnostic and development
+purposes. Many are good old \TEX\ constants that are describes in the original
+documentation of the source but some are definitely \LUAMETATEX\ specific.
+
+\startluacode
+ context.starttabulate { "|Tw(15em)|Tp|" }
+ context.DB()
+ context("constants.*")
+ context.BC()
+ context.NC()
+ context.NR()
+ context.TB()
+ for k, v in table.sortedhash(status.getconstants()) do
+ if type(v) ~= "table" then
+ context.NC()
+ context(k)
+ context.NC()
+ context(tostring(v))
+ context.NC()
+ context.NR()
+ end
+ end
+ context.LL()
+ context.stoptabulate()
+\stopluacode
+
+Most variables speak for themselves, some are more obscure. For instance the
+\type {run_state} variable indicates what the engine is doing:
+
+\starttabulate[|l|l|p|]
+\DB n \NC meaning \NC explanation \NC \NR
\TB
-\NC \type{banner} \NC terminal display banner \NC \NR
-\NC \type{best_page_break} \NC the current best break (a node) \NC \NR
-\NC \type{buf_size} \NC current allocated size of the line buffer \NC \NR
-\NC \type{callbacks} \NC total number of executed callbacks so far \NC \NR
-\NC \type{cs_count} \NC number of control sequences \NC \NR
-\NC \type{dest_names_size} \NC \PDF\ destination table size \NC \NR
-\NC \type{dvi_gone} \NC written \DVI\ bytes \NC \NR
-\NC \type{dvi_ptr} \NC not yet written \DVI\ bytes \NC \NR
-\NC \type{dyn_used} \NC token (multi|-|word) memory in use \NC \NR
-\NC \type{filename} \NC name of the current input file \NC \NR
-\NC \type{fix_mem_end} \NC maximum number of used tokens \NC \NR
-\NC \type{fix_mem_min} \NC minimum number of allocated words for tokens \NC \NR
-\NC \type{fix_mem_max} \NC maximum number of allocated words for tokens \NC \NR
-\NC \type{font_ptr} \NC number of active fonts \NC \NR
-\NC \type{hash_extra} \NC extra allowed hash \NC \NR
-\NC \type{hash_size} \NC size of hash \NC \NR
-\NC \type{indirect_callbacks} \NC number of those that were themselves a result of other callbacks (e.g. file readers) \NC \NR
-\NC \type{ini_version} \NC \type {true} if this is an \INITEX\ run \NC \NR
-\NC \type{init_pool_ptr} \NC \INITEX\ string pool index \NC \NR
-\NC \type{init_str_ptr} \NC number of \INITEX\ strings \NC \NR
-\NC \type{input_ptr} \NC the level of input we're at \NC \NR
-\NC \type{inputid} \NC numeric id of the current input \NC \NR
-\NC \type{largest_used_mark} \NC max referenced marks class \NC \NR
-\NC \type{lasterrorcontext} \NC last error context string (with newlines) \NC \NR
-\NC \type{lasterrorstring} \NC last \TEX\ error string \NC \NR
-\NC \type{lastluaerrorstring} \NC last \LUA\ error string \NC \NR
-\NC \type{lastwarningstring} \NC last warning tag, normally an indication of in what part\NC \NR
-\NC \type{lastwarningtag} \NC last warning string\NC \NR
-\NC \type{linenumber} \NC location in the current input file \NC \NR
-\NC \type{log_name} \NC name of the log file \NC \NR
-\NC \type{luabytecode_bytes} \NC number of bytes in \LUA\ bytecode registers \NC \NR
-\NC \type{luabytecodes} \NC number of active \LUA\ bytecode registers \NC \NR
-\NC \type{luastate_bytes} \NC number of bytes in use by \LUA\ interpreters \NC \NR
-\NC \type{luatex_engine} \NC the \LUATEX\ engine identifier \NC \NR
-\NC \type{luatex_hashchars} \NC length to which \LUA\ hashes strings ($2^n$) \NC \NR
-\NC \type{luatex_hashtype} \NC the hash method used (in \LUAJITTEX) \NC \NR
-\NC \type{luatex_version} \NC the \LUATEX\ version number \NC \NR
-\NC \type{luatex_revision} \NC the \LUATEX\ revision string \NC \NR
-\NC \type{max_buf_stack} \NC max used buffer position \NC \NR
-\NC \type{max_in_stack} \NC max used input stack entries \NC \NR
-\NC \type{max_nest_stack} \NC max used nesting stack entries \NC \NR
-\NC \type{max_param_stack} \NC max used parameter stack entries \NC \NR
-\NC \type{max_save_stack} \NC max used save stack entries \NC \NR
-\NC \type{max_strings} \NC maximum allowed strings \NC \NR
-\NC \type{nest_size} \NC nesting stack size \NC \NR
-\NC \type{node_mem_usage} \NC a string giving insight into currently used nodes \NC \NR
-\NC \type{obj_ptr} \NC max \PDF\ object pointer \NC \NR
-\NC \type{obj_tab_size} \NC \PDF\ object table size \NC \NR
-\NC \type{output_active} \NC \type {true} if the \prm {output} routine is active \NC \NR
-\NC \type{output_file_name} \NC name of the \PDF\ or \DVI\ file \NC \NR
-\NC \type{param_size} \NC parameter stack size \NC \NR
-\NC \type{pdf_dest_names_ptr} \NC max \PDF\ destination pointer \NC \NR
-\NC \type{pdf_gone} \NC written \PDF\ bytes \NC \NR
-\NC \type{pdf_mem_ptr} \NC max \PDF\ memory used \NC \NR
-\NC \type{pdf_mem_size} \NC \PDF\ memory size \NC \NR
-\NC \type{pdf_os_cntr} \NC max \PDF\ object stream pointer \NC \NR
-\NC \type{pdf_os_objidx} \NC \PDF\ object stream index \NC \NR
-\NC \type{pdf_ptr} \NC not yet written \PDF\ bytes \NC \NR
-\NC \type{pool_ptr} \NC string pool index \NC \NR
-\NC \type{pool_size} \NC current size allocated for string characters \NC \NR
-\NC \type{save_size} \NC save stack size \NC \NR
-\NC \type{shell_escape} \NC \type {0} means disabled, \type {1} means anything is permitted, and \type {2} is restricted \NC \NR
-\NC \type{safer_option} \NC \type {1} means safer is enforced \NC \NR
-\NC \type{kpse_used} \NC \type {1} means that kpse is used \NC \NR
-\NC \type{stack_size} \NC input stack size \NC \NR
-\NC \type{str_ptr} \NC number of strings \NC \NR
-\NC \type{total_pages} \NC number of written pages \NC \NR
-\NC \type{var_mem_max} \NC number of allocated words for nodes \NC \NR
-\NC \type{var_used} \NC variable (one|-|word) memory in use \NC \NR
-\NC \type{lc_collate} \NC the value of \type {LC_COLLATE} at startup time (becomes \type {C} at startup) \NC \NR
-\NC \type{lc_ctype} \NC the value of \type {LC_CTYPE} at startup time (becomes \type {C} at startup) \NC \NR
-%NC \type{lc_monetary} \NC the value of \type {LC_MONETARY} at startup time \NC \NR
-\NC \type{lc_numeric} \NC the value of \type {LC_NUMERIC} at startup time \NC \NR
-%NC \type{lc_time} \NC the value of \type {LC_TIME} at startup time (becomes \type {C} at startup) \NC \NR
+\NC 0 \NC initializing \NC \type {--ini} mnode \NC \NR
+\NC 1 \NC updating \NC relates to \lpr {overloadmode} \NC \NR
+\NC 2 \NC production \NC a regular (format driven) run \NC \NR
\LL
\stoptabulate
-The error and warning messages can be wiped with the \type {resetmessages}
-function. A return value can be set with \type {setexitcode}.
-
\stopsection
\startsection[title={The \type {tex} library}][library=tex]
@@ -284,7 +282,8 @@ readable (like \prm {tracingcommands} and \prm {parindent}).
\topicindex{parameters+internal}
-\libindex{set} \libindex{get}
+\libindex{set}
+\libindex{get}
For all the parameters in this section, it is possible to access them directly
using their names as index in the \type {tex} table, or by using one of the
@@ -307,152 +306,8 @@ get all five values. Otherwise you get a node which is a copy of the internal
value so you are responsible for its freeing at the \LUA\ end. When you set a
glue quantity you can either pass a \nod {glue_spec} or upto five numbers.
-\subsubsection{Integer parameters}
-
-The integer parameters accept and return \LUA\ numbers. These are read|-|write:
-
-\starttwocolumns
-\starttyping
-tex.adjdemerits
-tex.binoppenalty
-tex.brokenpenalty
-tex.catcodetable
-tex.clubpenalty
-tex.day
-tex.defaulthyphenchar
-tex.defaultskewchar
-tex.delimiterfactor
-tex.displaywidowpenalty
-tex.doublehyphendemerits
-tex.endlinechar
-tex.errorcontextlines
-tex.escapechar
-tex.exhyphenpenalty
-tex.fam
-tex.finalhyphendemerits
-tex.floatingpenalty
-tex.globaldefs
-tex.hangafter
-tex.hbadness
-tex.holdinginserts
-tex.hyphenpenalty
-tex.interlinepenalty
-tex.language
-tex.lastlinefit
-tex.lefthyphenmin
-tex.linepenalty
-tex.localbrokenpenalty
-tex.localinterlinepenalty
-tex.looseness
-tex.mag
-tex.maxdeadcycles
-tex.month
-tex.newlinechar
-tex.outputpenalty
-tex.pausing
-tex.postdisplaypenalty
-tex.predisplaydirection
-tex.predisplaypenalty
-tex.pretolerance
-tex.relpenalty
-tex.righthyphenmin
-tex.savinghyphcodes
-tex.savingvdiscards
-tex.showboxbreadth
-tex.showboxdepth
-tex.time
-tex.tolerance
-tex.tracingassigns
-tex.tracingcommands
-tex.tracinggroups
-tex.tracingifs
-tex.tracinglostchars
-tex.tracingmacros
-tex.tracingnesting
-tex.tracingonline
-tex.tracingoutput
-tex.tracingpages
-tex.tracingparagraphs
-tex.tracingrestores
-tex.tracingscantokens
-tex.tracingstats
-tex.uchyph
-tex.vbadness
-tex.widowpenalty
-tex.year
-\stoptyping
-\stoptwocolumns
-
-These are read|-|only:
-
-\startthreecolumns
-\starttyping
-tex.deadcycles
-tex.insertpenalties
-tex.parshape
-tex.prevgraf
-tex.spacefactor
-\stoptyping
-\stopthreecolumns
-
-\subsubsection{Dimension parameters}
-
-The dimension parameters accept \LUA\ numbers (signifying scaled points) or
-strings (with included dimension). The result is always a number in scaled
-points. These are read|-|write:
-
-\startthreecolumns
-\starttyping
-tex.boxmaxdepth
-tex.delimitershortfall
-tex.displayindent
-tex.displaywidth
-tex.emergencystretch
-tex.hangindent
-tex.hfuzz
-tex.hoffset
-tex.hsize
-tex.lineskiplimit
-tex.mathsurround
-tex.maxdepth
-tex.nulldelimiterspace
-tex.overfullrule
-tex.pagebottomoffset
-tex.pageheight
-tex.pageleftoffset
-tex.pagerightoffset
-tex.pagetopoffset
-tex.pagewidth
-tex.parindent
-tex.predisplaysize
-tex.scriptspace
-tex.splitmaxdepth
-tex.vfuzz
-tex.voffset
-tex.vsize
-tex.prevdepth
-tex.prevgraf
-tex.spacefactor
-\stoptyping
-\stopthreecolumns
-
-These are read|-|only:
-
-\startthreecolumns
-\starttyping
-tex.pagedepth
-tex.pagefilllstretch
-tex.pagefillstretch
-tex.pagefilstretch
-tex.pagegoal
-tex.pageshrink
-tex.pagestretch
-tex.pagetotal
-\stoptyping
-\stopthreecolumns
-
-Beware: as with all \LUA\ tables you can add values to them. So, the following is
-valid:
+Beware: as with regular \LUA\ tables you can add values to the \type {tex} table.
+So, the following is valid:
\starttyping
tex.foo = 123
@@ -484,70 +339,52 @@ as there is no way \LUATEX\ can guess your intentions. By using the accessor in
the \type {tex} tables, you get and set the values at the top of the nesting
stack.
-\subsubsection{Direction parameters}
+\subsubsection{Integer parameters}
-The direction states can be queried and set with:
+The integer parameters accept and return \LUA\ integers. In some cases the values
+are checked, trigger other settings or result in some immediate change of
+behaviour: \ctxlua {document.filteredprimitives ("internal_int")}.
-\startthreecolumns
-\starttyping
-tex.gettextdir()
-tex.getlinedir()
-tex.getmathdir()
-tex.getpardir()
-tex.settextdir(<number>)
-tex.setlinedir(<number>)
-tex.setmathdir(<number>)
-tex.setpardir(<number>)
-\stoptyping
-\stopthreecolumns
+Some integer parameters are read only, because they are actually referring not to
+some internal integer register but to an engine property: \typ {deadcycles},
+\typ {insertpenalties}, \typ {parshape}, \typ {interlinepenalties}, \typ
+{clubpenalties}, \typ {widowpenalties}, \typ {displaywidowpenalties}, \typ
+{prevgraf} and \typ {spacefactor}.
-and also with:
+\subsubsection{Dimension parameters}
-\startthreecolumns
-\starttyping
-tex.textdirection
-tex.linedirection
-tex.mathdirection
-tex.pardirection
-\stoptyping
-\stopthreecolumns
+The dimension parameters accept \LUA\ numbers (signifying scaled points) or
+strings (with included dimension). The result is always a number in scaled
+points. These are read|-|write: \ctxlua {document.filteredprimitives
+("internal_dimen")}.
+These are read|-|only: \typ {pagedepth}, \typ {pagefilllstretch}, \typ
+{pagefillstretch}, \typ {pagefilstretch}, \typ {pagegoal}, \typ {pageshrink},
+\typ {pagestretch} and \typ {pagetotal}.
-\subsubsection{Glue parameters}
+\subsubsection{Direction parameters}
-The glue parameters accept and return a userdata object that represents a \nod {glue_spec} node.
+The direction states can be queried with: \typ {gettextdir}, \typ {getlinedir},
+\typ {getmathdir} and \typ {getpardir}. You can set them with \typ
+{settextdir}, \typ {setlinedir}, \typ {setmathdir} and \typ {setpardir},
+commands that accept a number. You can also set these parameters as table
+key|/|values: \typ {textdirection}, \typ {linedirection}, \typ {mathdirection}
+and \typ {pardirection}, so the next code sets the text direction to \typ
+{r2l}:
-\startthreecolumns
\starttyping
-tex.abovedisplayshortskip
-tex.abovedisplayskip
-tex.baselineskip
-tex.belowdisplayshortskip
-tex.belowdisplayskip
-tex.leftskip
-tex.lineskip
-tex.parfillskip
-tex.parskip
-tex.rightskip
-tex.spaceskip
-tex.splittopskip
-tex.tabskip
-tex.topskip
-tex.xspaceskip
+tex.textdirection = 1
\stoptyping
-\stopthreecolumns
-\subsubsection{Muglue parameters}
+\subsubsection{Glue parameters}
-All muglue parameters are to be used read|-|only and return a \LUA\ string.
+The internal glue parameters accept and return a userdata object that represents
+a \nod {glue_spec} node: \ctxlua {document.filteredprimitives ("internal_glue")}.
-\startthreecolumns
-\starttyping
-tex.medmuskip
-tex.thickmuskip
-tex.thinmuskip
-\stoptyping
-\stopthreecolumns
+\subsubsection{Muglue parameters}
+
+All muglue parameters are to be used read|-|only and return a \LUA\ string
+\ctxlua {document.filteredprimitives ("internal_mu_glue")}.
\subsubsection{Tokenlist parameters}
@@ -556,22 +393,8 @@ converted to and from token lists using \prm {the} \prm {toks} style expansion:
all category codes are either space (10) or other (12). It follows that assigning
to some of these, like \quote {tex.output}, is actually useless, but it feels bad
to make exceptions in view of a coming extension that will accept full|-|blown
-token strings.
-
-\startthreecolumns
-\starttyping
-tex.errhelp
-tex.everycr
-tex.everydisplay
-tex.everyeof
-tex.everyhbox
-tex.everyjob
-tex.everymath
-tex.everypar
-tex.everyvbox
-tex.output
-\stoptyping
-\stopthreecolumns
+token strings. Here is the lot: \ctxlua {document.filteredprimitives
+("internal_toks")}.
\stopsubsection
@@ -580,55 +403,23 @@ tex.output
\topicindex{convert commands}
All \quote {convert} commands are read|-|only and return a \LUA\ string. The
-supported commands at this moment are:
-
-\starttwocolumns
-\starttyping
-tex.formatname
-tex.jobname
-tex.luatexbanner
-tex.luatexrevision
-tex.fontname(number)
-tex.uniformdeviate(number)
-tex.number(number)
-tex.romannumeral(number)
-tex.fontidentifier(number)
-\stoptyping
-\stoptwocolumns
-
-If you are wondering why this list looks haphazard; these are all the cases of
-the \quote {convert} internal command that do not require an argument, as well as
-the ones that require only a simple numeric value. The special (\LUA|-|only) case
-of \type {tex.fontidentifier} returns the \type {csname} string that matches a
-font id number (if there is one).
+supported commands at this moment are: \ctxlua {document.filteredprimitives
+("convert")}. You will get an error message if an operation is not (yet)
+permitted. Some take an string or number argument, just like at the \TEX\ end
+some extra input is expected.
\stopsubsection
-\startsubsection[title={Last item commands}]
+\startsubsection[title={Item commands}]
\topicindex{last items}
-All \quote {last item} commands are read|-|only and return a number. The
-supported commands at this moment are:
-
-\startthreecolumns
-\starttyping
-tex.lastpenalty
-tex.lastkern
-tex.lastskip
-tex.lastnodetype
-tex.inputlineno
-tex.lastxpos
-tex.lastypos
-tex.randomseed
-tex.luatexversion
-tex.currentgrouplevel
-tex.currentgrouptype
-tex.currentiflevel
-tex.currentiftype
-tex.currentifbranch
-\stoptyping
-\stopthreecolumns
+All so called \quote {item} commands are read|-|only and return a number. The
+complete list of these commands is: \ctxlua {document.filteredprimitives
+("some_item")}. No all are currently supported but eventually that might be the
+case. Like the lists in previous sections, there are differences between \LUATEX\
+and \LUAMETATEX, where some commands are organized differently in order to
+provide a consistent \LUA\ interface.
\stopsubsection
@@ -649,6 +440,8 @@ tex.currentifbranch
\libindex{scantoks}
+\libindex{getmark}
+
\TEX's attributes (\lpr {attribute}), counters (\prm {count}), dimensions (\prm
{dimen}), skips (\prm {skip}, \prm {muskip}) and token (\prm {toks}) registers
can be accessed and written to using two times five virtual sub|-|tables of the
@@ -734,17 +527,17 @@ We have similar setters for \type {count}, \type {dimen}, \type {muskip}, and
nodes, and toks by strings.
Again the glue variants are not using the \nod {glue-spec} userdata nodes. The
-\type {setglue} function accepts upto 5 arguments: width, stretch, shrink,
-stretch order and shrink order and the \type {getglue} function reports them,
-unless the second argument is \type {false} in which case only the width is
-returned.
+\type {setglue} function accepts upto five arguments: width, stretch, shrink,
+stretch order and shrink order. Non|-|numeric values set the property to zero.
+The \type {getglue} function reports all five properties, unless the second
+argument is \type {false} in which case only the width is returned.
Here is an example using a threesome:
\startfunctioncall
local d = tex.getdimen("foo")
-if tex.isdimen("bar") then
- tex.setdimen("bar",d)
+if tex.isdimen("oof") then
+ tex.setdimen("oof",d)
end
\stopfunctioncall
@@ -784,6 +577,15 @@ tex.scantoks("global",0,3,"$\int\limits^1_2$")
In the function-based interface, it is possible to define values globally by
using the string \type {global} as the first function argument.
+There is a dedicated getter for marks: \type {getmark} that takes two arguments.
+The first argument is one of \type {top}, \type {bottom}, \type {first}, \type
+{splitbottom} or \type {splitfirst}, and the second argument is a marks class
+number. When no arguments are given the current maximum number of classes is
+returned.
+
+When \type {tex.gettoks} gets an extra argument \type {true} it will return a
+table with userdata tokens.
+
\stopsubsection
\startsubsection[title={Character code registers: \type {[get|set]*code[s]}}]
@@ -1061,7 +863,7 @@ keep track of building page lists.
\DB field \BC explanation \NC \NR
\TB
\NC \type{page_ins_head} \NC circular list of pending insertions \NC \NR
-\NC \type{contrib_head} \NC the recent contributions \NC \NR
+\NC \type{contribute_head} \NC the recent contributions \NC \NR
\NC \type{page_head} \NC the current page content \NC \NR
%NC \type{temp_head} \NC \NC \NR
\NC \type{hold_head} \NC used for held-over items for next page \NC \NR
@@ -1120,7 +922,7 @@ The known fields are:
\NC \type{prevgraf} \NC number \NC vmode \NC number of lines in the previous paragraph \NC \NR
\NC \type{prevdepth} \NC number \NC vmode \NC depth of the previous paragraph \NC \NR
\NC \type{spacefactor} \NC number \NC hmode \NC the current space factor \NC \NR
-\NC \type{dirs} \NC node \NC hmode \NC used for temporary storage by the line break algorithm\NC \NR
+\NC \type{direction} \NC node \NC hmode \NC stack used for temporary storage by the line break algorithm \NC \NR
\NC \type{noad} \NC node \NC mmode \NC used for temporary storage of a pending fraction numerator,
for \prm {over} etc. \NC \NR
\NC \type{delimptr} \NC node \NC mmode \NC used for temporary storage of the previous math delimiter,
@@ -1524,14 +1326,15 @@ an error:
This function has two optional arguments in case a token register is passed:
\startfunctioncall
-tex.runtoks(<token register>,force,grouped)
+tex.runtoks(<token register>,force,grouped,obeymode)
\stopfunctioncall
Inside for instance an \type {\edef} the \type {runtoks} function behaves (at
least tries to) like it were an \type {\the}. This prevents unwanted side
effects: normally in such an definition tokens remain tokens and (for instance)
characters don't become nodes. With the second argument you can force the local
-main loop, no matter what. The third argument adds a level of grouping.
+main loop, no matter what. The third argument adds a level of grouping. The last
+argument tells the scanner to stay in the current mode.
You can quit the local loop with \type {\endlocalcontrol} or from the \LUA\ end
with \type {tex.quittoks}. In that case you end one level up! Of course in the
@@ -1657,20 +1460,6 @@ given by the requested string value(s). The possible values and their (current)
return values are given in the following table. In addition the somewhat special
primitives \quote{\tex{ }}, \quote{\tex {/}} and \quote{\type {-}} are defined.
-\startluacode
-function document.showprimitives(tag)
- local t = tex.extraprimitives(tag)
- table.sort(t)
- for i=1,#t do
- local v = t[i]
- if v ~= ' ' and v ~= "/" and v ~= "-" then
- context.type(v)
- context.space()
- end
- end
-end
-\stopluacode
-
\starttabulate[|l|pl|]
\DB name \BC values \NC \NR
\TB
@@ -1750,7 +1539,7 @@ The understood parameters are as follows:
\NC \type{exhyphenpenalty} \NC number \NC \NC \NR
\NC \type{pdfadjustspacing} \NC number \NC \NC \NR
\NC \type{adjdemerits} \NC number \NC \NC \NR
-\NC \type{pdfprotrudechars} \NC number \NC \NC \NR
+\NC \type{protrudechars} \NC number \NC \NC \NR
\NC \type{linepenalty} \NC number \NC \NC \NR
\NC \type{lastlinefit} \NC number \NC \NC \NR
\NC \type{doublehyphendemerits} \NC number \NC \NC \NR
@@ -1781,7 +1570,7 @@ horizontal mode):
\startitemize
\startitem
- add an \quote {indent box} and perhaps a \nod {local_par} node at the start
+ add an \quote {indent box} and perhaps a \nod {par} node at the start
(only if you need them)
\stopitem
\startitem
@@ -1969,8 +1758,8 @@ texio.write(<string> s, ...)
Without the \type {target} argument, writes all given strings to the same
location(s) \TEX\ writes messages to at this moment. If \prm {batchmode} is in
effect, it writes only to the log, otherwise it writes to the log and the
-terminal. The optional \type {target} can be one of three possibilities: \type
-{term}, \type {log} or \type {term and log}.
+terminal. The optional \type {target} can be one of \type {terminal},
+\type {logfile} or \type {terminal_and_logfile}.
Note: If several strings are given, and if the first of these strings is or might
be one of the targets above, the \type {target} must be specified explicitly to
@@ -2071,6 +1860,9 @@ most intriguing.
\LL
\stoptabulate
+The integer, dimension and glue scanners take an extra optional argument that
+signals that en optional equal is permitted.
+
The scanners can be considered stable apart from the one scanning for a token.
The \type {scan_code} function takes an optional number, the \type {scan_keyword}
function a normal \LUA\ string. The \type {infinity} boolean signals that we also
@@ -2080,14 +1872,19 @@ macro, in which case the result will also provide information about what
arguments are expected and in the result this is separated from the meaning by a
separator token. The \type {expand} flag determines if the list will be expanded.
+The \type {scan_argument} function expands the given argument. When a braced
+argument is scanned, expansion can be prohibited by passing \type {false}
+(default is \type {true}). In case of a control sequence passing \type {false}
+will result in a one|-|level expansion (the meaning of the macro).
+
The string scanner scans for something between curly braces and expands on the
way, or when it sees a control sequence it will return its meaning. Otherwise it
will scan characters with catcode \type {letter} or \type {other}. So, given the
following definition:
\startbuffer
-\def\bar{bar}
-\def\foo{foo-\bar}
+\def\oof{oof}
+\def\foo{foo-\oof}
\stopbuffer
\typebuffer \getbuffer
@@ -2108,7 +1905,9 @@ expanded definition (\prm {edef}'d). In the case of the braced variant one can o
course use the \prm {detokenize} and \prm {unexpanded} primitives since there we
do expand.
-The \type {scan_word} scanner can be used to implement for instance a number scanner:
+The \type {scan_word} scanner can be used to implement for instance a number
+scanner. An optional boolean argument can signal that a trailing space or \type
+{\relax} should be gobbled:
\starttyping
function token.scan_number(base)
@@ -2176,22 +1975,43 @@ a bit but for passing strings conversion to and from tokens has to be done anywa
\startsubsection[title={Picking up one token}]
-\libindex {get_next}
+\libindex {scan_next}
+\libindex {scan_next_expanded}
+\libindex {skip_next}
+\libindex {skip_next_expanded}
+\libindex {peek_next}
+\libindex {peek_next_expanded}
\libindex {scan_token}
\libindex {expand}
The scanners look for a sequence. When you want to pick up one token from the
-input you use \type {get_next}. This creates a token with the (low level)
+input you use \type {scan_next}. This creates a token with the (low level)
properties as discussed next. This token is just the next one. If you want to
-enforce expansion first you can use \type {scan_token}. Internally tokens are
-characterized by a number that packs a lot of information. In order to access
-the bits of information a token is wrapped in a userdata object.
+enforce expansion first you can use \type {scan_token} or the \type {_expanded}
+variants. Internally tokens are characterized by a number that packs a lot of
+information. In order to access the bits of information a token is wrapped in a
+userdata object.
The \type {expand} function will trigger expansion of the next token in the
input. This can be quite unpredictable but when you call it you probably know
enough about \TEX\ not to be too worried about that. It basically is a call to
the internal expand related function.
+\starttabulate[|lT|p|]
+\DB name \BC explanation \NC \NR
+\TB
+\NC scan_next \NC get the next token \NC \NR
+\NC scan_next_expanded \NC get the next expanded token \NC \NR
+\NC skip_next \NC skip the next token \NC \NR
+\NC skip_next_expanded \NC skip the next expanded token \NC \NR
+\NC peek_next \NC get the next token and put it back in the input \NC \NR
+\NC peek_next_expanded \NC get the next expanded token and put it back in the input \NC \NR
+\LL
+\stoptabulate
+
+The peek function accept a boolean argument that triggers skipping spaces and
+alike.
+
\stopsubsection
\startsubsection[title={Creating tokens}]
@@ -2216,8 +2036,10 @@ the internal expand related function.
\libindex{get_mode}
\libindex{get_index}
\libindex{get_tok}
+\libindex{get_frozen}
+\libindex{get_user}
-\libindex{get_next}
+\libindex{scan_next}
The creator function can be used as follows:
@@ -2241,8 +2063,9 @@ primitive. The possible properties of tokens are:
\NC \type {active} \NC a boolean indicating the active state of the token \NC \NR
\NC \type {expandable} \NC a boolean indicating if the token (macro) is expandable \NC \NR
\NC \type {protected} \NC a boolean indicating if the token (macro) is protected \NC \NR
-\NC \type {mode} \NC a number either representing a character or another entity \NC \NR
-\NC \type {index} \NC a number running from 0x0000 upto 0xFFFF indicating a \TEX\ register index \NC \NR
+\NC \type {frozen} \NC a boolean indicating if the token is a frozen command \NC \NR
+\NC \type {user} \NC a boolean indicating if the token is a user defined command \NC \NR
+\NC \type {index} \NC a number that indicated the subcommand; differs per command \NC \NR
\LL
\stoptabulate
@@ -2307,6 +2130,8 @@ need to know that boundary condition.
\libindex{set_char}
\libindex{set_lua}
\libindex{get_functions_table}
+\libindex{push_macro}
+\libindex{pop_macro}
The \type {set_macro} function can get upto 4 arguments:
@@ -2356,20 +2181,25 @@ that you can access with \type {lua.get_functions_table}. It is the companion
to \lpr {luadef}. When the first (and only) argument is true the size will preset
to the value of \type {texconfig.function_size}.
+The \type {push_macro} and \type {pop_macro} function are very experimental and
+can be used to get and set an existing macro. The push call returns a user data
+object and the pop takes such a userdata object. These object have no accessors
+and are to be seen as abstractions.
+
\stopsubsection
\startsubsection[title={Pushing back}]
-\libindex{get_next}
+\libindex{scan_next}
\libindex{put_next}
There is a (for now) experimental putter:
\starttyping
-local t1 = token.get_next()
-local t2 = token.get_next()
-local t3 = token.get_next()
-local t4 = token.get_next()
+local t1 = token.scan_next()
+local t2 = token.scan_next()
+local t3 = token.scan_next()
+local t4 = token.scan_next()
-- watch out, we flush in sequence
token.put_next { t1, t2 }
-- but this one gets pushed in front
@@ -2410,28 +2240,28 @@ When scanning for the next token you need to keep in mind that we're not scannin
like \TEX\ does: expanding, changing modes and doing things as it goes. When we
scan with \LUA\ we just pick up tokens. Say that we have:
-\pushmacro\bar \let\bar\undefined
+\pushmacro\oof \let\oof\undefined
\starttyping
-\bar
+\oof
\stoptyping
-but \type {\bar} is undefined. Normally \TEX\ will then issue an error message.
+but \type {\oof} is undefined. Normally \TEX\ will then issue an error message.
However, when we have:
\starttyping
-\def\foo{\bar}
+\def\foo{\oof}
\stoptyping
-We get no error, unless we expand \type {\foo} while \type {\bar} is still
+We get no error, unless we expand \type {\foo} while \type {\oof} is still
undefined. What happens is that as soon as \TEX\ sees an undefined macro it will
create a hash entry and when later it gets defined that entry will be reused. So,
-\type {\bar} really exists but can be in an undefined state.
+\type {\oof} really exists but can be in an undefined state.
\startbuffer[demo]
-bar : \directlua{tex.print(token.scan_csname())}\bar
+oof : \directlua{tex.print(token.scan_csname())}\oof
foo : \directlua{tex.print(token.scan_csname())}\foo
-myfirstbar : \directlua{tex.print(token.scan_csname())}\myfirstbar
+myfirstoof : \directlua{tex.print(token.scan_csname())}\myfirstoof
\stopbuffer
\startlines
@@ -2442,8 +2272,8 @@ This was entered as:
\typebuffer[demo]
-The reason that you see \type {bar} reported and not \type {myfirstbar} is that
-\type {\bar} was already used in a previous paragraph.
+The reason that you see \type {oof} reported and not \type {myfirstoof} is that
+\type {\oof} was already used in a previous paragraph.
If we now say:
@@ -2462,7 +2292,7 @@ we get:
And if we say
\startbuffer
-\def\foo{\bar}
+\def\foo{\oof}
\stopbuffer
\typebuffer \getbuffer
@@ -2477,9 +2307,9 @@ When scanning from \LUA\ we are not in a mode that defines (undefined) macros at
all. There we just get the real primitive undefined macro token.
\startbuffer
-\directlua{local t = token.get_next() tex.print(t.id.." "..t.tok)}\myfirstbar
-\directlua{local t = token.get_next() tex.print(t.id.." "..t.tok)}\mysecondbar
-\directlua{local t = token.get_next() tex.print(t.id.." "..t.tok)}\mythirdbar
+\directlua{local t = token.scan_next() tex.print(t.id.." "..t.tok)}\myfirstoof
+\directlua{local t = token.scan_next() tex.print(t.id.." "..t.tok)}\mysecondoof
+\directlua{local t = token.scan_next() tex.print(t.id.." "..t.tok)}\mythirdoof
\stopbuffer
\startlines
@@ -2494,7 +2324,7 @@ So, we do get a unique token because after all we need some kind of \LUA\ object
that can be used and garbage collected, but it is basically the same one,
representing an undefined control sequence.
-\popmacro\bar
+\popmacro\oof
\stopsubsection
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex.tex
new file mode 100644
index 00000000000..1327ea3a14b
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex.tex
@@ -0,0 +1,132 @@
+% ------------------------ ------------------------ ------------------------
+% 2019-12-17 32bit 64bit 2020-01-10 32bit 64bit 2020-11-30 32bit 64bit
+% ------------------------ ------------------------ ------------------------
+% freebsd 2270k 2662k freebsd 2186k 2558k freebsd 2108k 2436k
+% openbsd6.6 2569k 2824k openbsd6.6 2472k 2722k openbsd6.8 2411k 2782k
+% linux-armhf 2134k linux-armhf 2063k linux-armhf 2138k 2860k
+% linux 2927k 2728k linux 2804k 2613k linux (?) 3314k 2762k
+% linux-musl 2532k 2686k
+% osx 2821k osx 2732k osx 2711k
+% ms mingw 2562k 2555k ms mingw 2481k 2471k ms mingw 2754k 2760k
+% ms intel 2448k
+% ms arm 3894k
+% ms clang 2159k
+% ------------------------ ------------------------ ------------------------
+%
+% performance of mingw and native are getting close (small win for mingw) but
+% clang bins are still slower .. quite inconsistent differences between 32 and
+% 64 bit (not all compilers are the same version)
+
+% \loggingall
+% \tracingonline \zerocount
+% \tracingmacros \plusone
+
+% \enableautoglyphscaling % saves only a few instances ... no gain .. a few pages more
+
+% \enabletexdirective{vspacing.experimental}
+
+% \nopdfcompression
+
+% 20200509 : 258 pages
+%
+% my 2013 i7 laptop with windows : 11.8 sec mingw64
+% raspberry pi 64 bit with ssd : 39.5 sec gcc 9.2
+% idem with native bin : 38.5 sec
+% idem overclocked f=2000/v=6 : 31.5 sec
+%
+% 20200526 : 258 pages
+% mingw all in: 10.9 / rpi 32 bit: 33.1
+
+% 20200610 : 258 pages
+% mingw all in: 10.6
+
+% 20201204 : 260 pages
+% mingw all in: 10.0
+
+% 20201204 : 262 pages
+% mingw all in: 9.9
+
+% 20200720 : 258 pages / all in
+%
+% mingw : 10.6 (sometimes less)
+% rpi 32 : 32.3
+% rpi 64 : 26.0 (overclocked)
+% amd 10 fitlet : 28.2
+
+% But speed can differ a bit per compilation (upto .5 seconds maybe due to how
+% compiled code is organized which might influence caching. Who knows ... (or
+% cares). For instance at 20200407 I measured 10.9 seconds after some new low level
+% metapost magic was added but who knows if that was the reason, because mp
+% processing is already fast. A week later, at 20200415, a by then 254 page file
+% took 10.5 seconds, that is, we were at exactly 24 pages per second but after
+% switching to gcc9 it dropped again. In december 2020, with IPO enabled I crossed
+% the 26 pps barrier and went below 10 seconds but that was also after some further
+% cleanup in \LMTX.
+
+% msvc 1899k (2% slower than mingw)
+% msvc /GL 2297k (similar to mingw)
+% msvc /GL /Ob3 2847k (not faster than /GL)
+% msvc /Ob3 2052k (slower than /Ob2)
+% msvc /Ob1 1763k (slower than /Ob2)
+% clang 2460k (15% slower than mingw)
+
+% Thanks to sebastian.miele@gmail.com for close reading the manual and sending
+% fixes.
+
+% \listcallbackmode0
+
+% 290 pages, 10.8 sec, 292M lua, 99M tex, 158 instances
+% 290 pages, 9.5 sec, 149M lua, 35M tex, 30 instances
+
+\enableexperiments[fonts.compact]
+% \enabledirectives[fonts.injections.method=advance] % tricky ... not all xoffsets are advance robust
+
+\pushoverloadmode \unprotect
+ % test code
+\protect \popoverloadmode
+
+\enabletrackers[system.usage=summary]
+
+\environment luametatex-style
+\environment luametatex-private
+
+\startdocument
+ [manual=LuaMeta\TeX,
+ %status=experimental,
+ version=\cldcontext{status.luatex_verbose}]
+
+\component luametatex-titlepage
+\component luametatex-firstpage
+
+\startfrontmatter
+ \component luametatex-contents
+ \component luametatex-introduction
+\stopfrontmatter
+
+\startbodymatter
+ \component luametatex-preamble
+ \component luametatex-differences
+ \component luametatex-modifications
+ \component luametatex-lua
+ \component luametatex-enhancements
+ \component luametatex-fonts
+ \component luametatex-languages
+ \component luametatex-math
+ \component luametatex-nodes
+ \component luametatex-callbacks
+ \component luametatex-tex
+ \component luametatex-metapost
+ \component luametatex-pdf
+ \component luametatex-libraries
+ \component luametatex-primitives
+\stopbodymatter
+
+\startbackmatter
+ % \component luametatex-rejected % local file
+ \component luametatex-codes
+ \component luametatex-registers
+ \component luametatex-statistics
+\stopbackmatter
+
+\stopdocument
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex
index b81e1dbdae5..537961661f5 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex
@@ -1266,6 +1266,29 @@ related primitives.
\stopsubsection
+\startsubsection[title={\prm {glyphdimensionsmode}}]
+
+Already in the early days of \LUATEX\ the decision was made to calculate the
+effective height and depth of glyphs in a way that reflected the applied vertical
+offset. The height got that offset added, the depth only when the offset was
+larger than zero. We can now control this in more detail with this mode
+parameter. An offset is added to the height and|/|or subtracted from the depth.
+The effective values are never negative. The zero mode is the default.
+
+\starttabulate[|l|pl|]
+\DB value \BC effect \NC\NR
+\TB
+\NC \type {0} \NC the old behaviour: add the offset to the height and only subtract
+ the offset only from the depth when it is positive \NC \NR
+\NC \type {1} \NC add the offset to the height and subtract it from the depth \NC \NR
+\NC \type {2} \NC add the offset to the height and subtract it from the depth but
+ keep the maxima of the current and previous results \NC \NR
+\NC \type {3} \NC use the height and depth of the glyph, so no offset is applied \NC \NR
+\LL
+\stoptabulate
+
+\stopsubsection
+
\stopsection
\startsection[title={Control and debugging}]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-fonts.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-fonts.tex
index 400550a96dd..e944b2c5b56 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-fonts.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-fonts.tex
@@ -861,6 +861,27 @@ value is the index in \type {font.fonts}, the second the font itself, as a \LUA\
table. The indices are listed incrementally, but they do not always form an array
of consecutive numbers: in some cases there can be holes in the sequence.
+\startsubsection[title={\type{\glyphdimensionsmode}}]
+
+Already in the early days of \LUATEX\ the decision was made to calculate the
+effective height and depth of glyphs in a way that reflected the applied vertical
+offset. The height got that offset added, the depth only when the offset was
+larger than zero. We can now control this in more detail with this mode
+parameter. An offset is added to the height and|/|or subtracted from the depth.
+The effective values are never negative. The zero mode is the default.
+
+\starttabulate[|l|pl|]
+\DB value \BC effect \NC\NR
+\TB
+\NC \type {0} \NC the old behavior: add the offset to the height and only subtract
+ the offset only from the depth when it is positive \NC \NR
+\NC \type {1} \NC add the offset to the height and subtract it from the depth \NC \NR
+\NC \type {2} \NC add the offset to the height and subtract it from the depth but
+ keep the maxima of the current and previous results \NC \NR
+\NC \type {3} \NC use the height and depth of the glyph, so no offset is applied \NC \NR
+\LL
+\stoptabulate
+
\stopsection
\stopchapter
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-lua.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-lua.tex
index f9107fa1f96..625334c1b8a 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-lua.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-lua.tex
@@ -608,6 +608,10 @@ in addition to the regular \type {io} library functions.
\NC \type{readbytetable(f,n)} \NC \type {n} bytes\NC \NR
\stoptabulate
+There are eight additional little endian variants for the \type {cardinal[1-4]}
+and \type {integer[1-4]} readers: \type {cardinal[1-4]le} and \type
+{integer[1-4]le}.
+
\stopsubsection
\startsubsection[title={Binary input from strings with \type {sio}}]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-math.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-math.tex
index 4623ce706d7..89c0836ba76 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-math.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-math.tex
@@ -1242,6 +1242,31 @@ $\Uhextensible width 1pt middle 0 "2194$
font metrics are involved we have a different code path for traditional fonts end
\OPENTYPE\ fonts.
+Sometimes you might want to act upon the size of a delimiter, something that is
+not really possible because of the fact that they are calculated {\em after} most
+has been typeset already. In the following example the all|-|zero specification
+is the trigger to make a fake box with the last delimiter dimensions and shift.
+It's an ugly hack but its relative simple and not intrusive implementation has no
+side effects. Any other heuristic solution would not satisfy possible demands
+anyway. Here is a rather low level example:
+
+\startbuffer
+\startformula
+\Uleft \Udelimiter 5 0 "222B
+\frac{\frac{a}{b}}{\frac{c}{d}}
+\Uright \Udelimiter 5 0 "222B
+\kern-2\fontcharwd\textfont0 "222B
+\mathlimop{\Uvextensible \Udelimiter 0 0 0}_1^2 x
+\stopformula
+\stopbuffer
+
+\typebuffer
+
+The last line, by passing zero values, results in a fake operator that has the
+dimensions of the previous delimiter. We can then backtrack over the (presumed)
+width and the two numbers become limit operators. As said, it's not pretty but it
+works.
+
\subsection{Fractions}
\topicindex {math+fractions}
@@ -1306,6 +1331,9 @@ For Latin Modern the result looks as follows:
\stoptabulate
\stop
+The keyword \type {norule} will hide the rule with the above variants while
+keeping the rule related spacing.
+
\subsection {Delimiters: \type{\Uleft}, \prm {Umiddle} and \prm {Uright}}
\topicindex {math+delimiters}
@@ -1454,7 +1482,7 @@ $
$
\stopbuffer
-\typebuffer
+\typebuffer[script]
results in \inlinebuffer[script].
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-modifications.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-modifications.tex
index 747945f55f7..bf4233165b9 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-modifications.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-modifications.tex
@@ -615,6 +615,8 @@ primitives (for as far their functionality is still around) you now can do this:
\protected\def\pdfmapline {\pdfextension mapline }
\protected\def\pdftrailer {\pdfextension trailer }
\protected\def\pdfglyphtounicode {\pdfextension glyphtounicode }
+\protected\def\pdfrunninglinkoff {\pdfextension linkstate 1 }
+\protected\def\pdfrunninglinkon {\pdfextension linkstate 0 }
\stoptyping
The introspective primitives can be defined as:
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-nodes.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
index 21e8a2808fe..a379b7b0a4d 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
@@ -1935,8 +1935,8 @@ character protrusion is active, this node can be skipped.
\libindex {setglue}
-You can set the properties of a glue in one go. If you pass no values, the glue
-will become a zero glue.
+You can set the five properties of a glue in one go. Non|-|numeric values are
+equivalent to zero and reset a property.
\startfunctioncall
node.setglue(<node> n)
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex.tex
index 5a98f224379..46739513a60 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex.tex
@@ -1,4 +1,4 @@
-% macros=mkvi
+% macros=mkvi engine=luatex
% \nopdfcompression
@@ -23,6 +23,13 @@
% comment : Some (parts of) 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 : Of course specific distribution can add to the manual, but that is of course not
+% our responsibility. The official (latest) version of this manual is part of the
+% ConTeXt distribution, including a pdf file that is produced with the current
+% version of ConTeXt. So, in case of doubt use that one as reference. Some of the
+% improvements in the LuaMetaTeX manual that apply to LuaTeX might get retrofitted
+% in LuaTeX manual in due time.
% \tex vs \type vs \syntax vs. \luatex
% \em \it \/
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/mathml/envexamp.tex b/Master/texmf-dist/doc/context/sources/general/manuals/mathml/envexamp.tex
index 99bc72b8a6e..8a2b4e2df55 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/mathml/envexamp.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/mathml/envexamp.tex
@@ -219,7 +219,7 @@
\startsubsection[reference=#1,title=#1,marking=#1][filename=#1]
\switchtobodyfont
[8pt]
- \startcolumns[balance=no,n=\getvariable{document}{columns}]
+ \startcolumns[balance=no,n=\documentvariable{columns}]
\typefile{#1.xml}
\stopcolumns
\vfill
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/mcommon.tex b/Master/texmf-dist/doc/context/sources/general/manuals/mcommon.tex
index d4c2acb53b8..57ab24a8d97 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/mcommon.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/mcommon.tex
@@ -167,7 +167,7 @@
[rotation=90]
{\color
[lightgray]
- {\getvariable{document}{title}}}
+ {\documentvariable{title}}}
\par
\stopstandardmakeup
\setupbackgrounds
@@ -179,9 +179,9 @@
\blank[2*big]
\testpage[3]
\startpacked
- \getvariable{document}{author}\par
- \getvariable{document}{affiliation}\par
- \getvariable{document}{location}\par
+ \documentvariable{author}\par
+ \documentvariable{affiliation}\par
+ \documentvariable{location}\par
\stoppacked
\stopsetups
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/gracht.mp b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/gracht.mp
new file mode 100644
index 00000000000..5076c729ae1
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/gracht.mp
@@ -0,0 +1,1284 @@
+% 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 (0.8,0.9,1));
+linecap := butt;
+linejoin := mitered;
+fill (34.0598,214.47)--(286.57,214.47)--(285.2,72.9199)
+ --(38.1699,83.8599)--(34.0598,214.47)--cycle;
+drawoptions (withcolor (0.95,0.95,0.95));
+fill (62,152.91)..controls (62,152.91) and (74.24,150.18)..(77.6199,152.91)
+ ..controls (81.0798,155.65) and (98.0698,152.91)..(98.0698,152.91)
+ ..controls (98.0698,152.91) and (106.21,148.81)..(111.68,148.81)
+ ..controls (117.15,148.81) and (130.76,147.37)..(130.76,147.37)
+ --(134.86,140.53)..controls (134.86,140.53) and (130.11,139.88)..(123.92,139.88)
+ ..controls (117.8,139.88) and (98.72,139.23)..(98.72,139.23)
+ --(82.3799,139.23)--(72.1499,145.35)--(64.0198,147.37)
+ --(62,152.91)--cycle;
+drawoptions (withcolor (0.9,0.9,0.9));
+fill (202.11,112.52)--(200.82,126.85)--(184.47,117.99)
+ --(170.86,116.62)--(150.42,117.34)--(141.63,114.61)
+ --(104.19,115.26)--(87.1299,115.26)--(69.49,113.17)
+ --(74.96,107.77)--(106.21,108.42)--(140.98,108.42)
+ --(147.03,110.5)--(165.39,110.5)--(164.74,104.38)
+ --(172.88,103.74)--(285.92,79.0398)--(285.2,98.9099)
+ --(271.59,100.93)--(202.11,112.52)--cycle;
+drawoptions (withcolor (1,0.4,0.4));
+fill (285.92,193.23)--(259.78,193.23)--(259.78,188.7)
+ --(277.35,148.88)--(285.92,155.72)--(285.92,193.23)
+ --cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0.86bp;
+draw (285.92,193.23)--(259.78,193.23)--(259.78,188.7)
+ --(277.35,148.88)--(285.92,155.72)--(285.92,193.23);
+drawoptions (withcolor (1,0.9,0.9));
+pickup pencircle scaled 0bp;
+fill (231.85,165.66)--(235.95,169.69)--(246.75,170.62)
+ --(273.32,149.82)--(272.89,101)--(235.02,107.34)
+ --(231.85,165.66)--cycle;
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 0.86bp;
+draw (231.85,165.66)--(235.95,169.69)--(246.75,170.62)
+ --(273.32,149.82)--(272.89,101)--(235.02,107.34)
+ --(231.85,165.66);
+drawoptions (withcolor (0,0.5,0));
+pickup pencircle scaled 0bp;
+fill (178.28,133.26)..controls (178.28,133.26) and (175.98,132.39)..(175.11,130.09)
+ ..controls (174.25,127.78) and (172.38,125.62)..(172.38,125.62)
+ ..controls (172.38,125.62) and (170.86,124.47)..(170,121.88)
+ ..controls (169.21,119.36) and (168.99,119.14)..(168.99,118.06)
+ ..controls (168.99,116.98) and (169.21,116.19)..(170.43,116.41)
+ ..controls (171.73,116.55) and (172.81,117.63)..(172.81,117.63)
+ --(175.33,116.84)..controls (175.33,116.84) and (175.9,116.62)..(177.42,117.85)
+ ..controls (178.86,119.14) and (179.29,121.52)..(179.72,120.22)
+ ..controls (180.15,118.93) and (179.94,119.58)..(180.73,118.06)
+ ..controls (181.59,116.55) and (183.03,115.98)..(184.11,116.41)
+ ..controls (185.19,116.84) and (184.47,115.69)..(185.55,117.2)
+ ..controls (186.63,118.71) and (185.19,122.74)..(185.19,122.74)
+ --(182.24,132.39)--(178.28,133.26)--cycle;
+drawoptions (withcolor (0,0.6,0));
+fill (203.19,132.82)..controls (207.44,132.82) and (198.58,125.84)..(194.55,123.61)
+ ..controls (190.45,121.3) and (188.65,115.04)..(184.11,120.87)
+ ..controls (179.65,126.7) and (184.54,132.61)..(180.51,133.04)
+ ..controls (176.48,133.54) and (177.85,132.18)..(174.68,133.54)
+ ..controls (171.51,134.84) and (172.45,140.31)..(172.45,140.31)
+ ..controls (172.45,140.31) and (175.98,145.71)..(177.42,148.88)
+ ..controls (178.78,152.05) and (177.42,152.91)..(177.85,155.22)
+ ..controls (178.28,157.52) and (181.02,159.32)..(181.02,159.32)
+ --(190.02,158.82)--(192.25,162.78)..controls (192.25,162.78) and (196.78,162.92)..(199.02,161.12)
+ ..controls (201.25,159.32) and (201.25,156.58)..(201.25,156.58)
+ --(203.98,155.22)--(203.55,147.58)--(201.68,143.12)
+ ..controls (201.68,143.12) and (201.82,139.95)..(203.19,137.72)
+ ..controls (204.56,135.42) and (202.76,132.82)..(203.19,132.82)
+ --cycle;
+drawoptions (withcolor (0.8,0.8,0.8));
+fill (1.37988,135.34)--(63.9399,129.01)--(67.98,114.97)
+ --(73.8799,108.63)--(57.6799,89.26)--(0.869873,46.2798)
+ --(1.37988,135.34)--cycle;
+drawoptions (withcolor (0,0.6,0));
+fill (141.27,120.87)..controls (140.84,121.23) and (143.65,122.46)..(139.62,123.32)
+ ..controls (135.51,124.26) and (134.65,122.67)..(129.25,122.67)
+ ..controls (123.85,122.67) and (124.28,120.87)..(122.05,122.67)
+ ..controls (119.82,124.47) and (119.38,126.27)..(115.28,126.27)
+ ..controls (111.25,126.27) and (109.45,126.7)..(106.78,124.9)
+ ..controls (104.05,123.1) and (102.68,123.1)..(100.45,123.1)
+ ..controls (98.22,123.1) and (96.3398,123.18)..(93.6799,123.61)
+ ..controls (91.0198,124.04) and (88.7798,124.47)..(86.0498,124.9)
+ ..controls (83.3098,125.41) and (80.5798,125.84)..(77.9099,125.41)
+ ..controls (75.25,124.9) and (70.2798,124.47)..(66.6799,124.9)
+ ..controls (63.0798,125.41) and (60.3398,127.21)..(57.1799,125.41)
+ ..controls (54.0798,123.61) and (49.1099,123.61)..(49.1099,123.61)
+ --(44.1399,122.67)--(45.0798,115.9)..controls (45.0798,115.9) and (43.2798,113.6)..(49.5398,113.6)
+ ..controls (55.8799,113.6) and (58.98,113.6)..(64.8799,113.6)
+ ..controls (70.71,113.6) and (69.4199,112.66)..(76.1099,114.03)
+ ..controls (82.8799,115.47) and (86.98,115.47)..(91.8799,115.47)
+ ..controls (96.8499,115.47) and (100.88,114.97)..(105.85,114.97)
+ ..controls (110.82,114.97) and (112.62,114.97)..(118.02,114.97)
+ ..controls (123.42,114.97) and (125.22,114.54)..(136.02,114.54)
+ ..controls (146.74,114.54) and (146.74,115.9)..(146.74,115.9)
+ --(145.88,120.37)--(141.27,120.87)--cycle;
+drawoptions (withcolor (0.5,0.5,0.5));
+fill (5.83984,98.26)--(27.5098,109.14)--(46.3799,113.6)
+ --(70.2798,114.03)--(74.3098,109.57)--(49.5398,105.54)
+ --(0.869873,67.95)--(5.83984,98.26)--cycle;
+drawoptions (withcolor (0.8,0.3,0));
+fill (105.85,108.2)--(106.78,85.23)--(73.8799,84.2998)
+ --(66.25,38.1399)--(36.7998,1.05981)--(0.72998,1.05981)
+ --(0.869873,49.8799)..controls (0.869873,49.8799) and (24.7798,67.0898)..(36.0798,74.7898)
+ ..controls (47.3098,82.5) and (70.2798,104.6)..(72.5098,107.34)
+ ..controls (74.74,110) and (77.48,108.2)..(77.48,108.2)
+ --(105.85,108.2)--cycle;
+drawoptions (withcolor (0.6,0.3,0));
+fill (75.25,107.77)--(105.85,107.77)--(105.85,85.23)
+ --(75.25,85.23)--(75.25,107.77)--cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0.86bp;
+draw (75.25,107.77)--(105.85,107.77)--(105.85,85.23)
+ --(75.25,85.23)--(75.25,107.77);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 2.23bp;
+draw (118.59,71.1899)--(117.22,61.8999);
+drawoptions (withcolor (0.9,0.95,1));
+pickup pencircle scaled 0bp;
+fill (266.48,1.56982)--(267.34,45.9199)--(158.84,82.3499)
+ --(149.26,81.2)--(144.15,86.3098)--(140.84,107.77)
+ --(104.84,107.26)--(105.92,86.3098)--(114.92,40.45)
+ --(55.5898,38.5798)--(37.23,0.849854)--(266.48,1.56982)
+ --cycle;
+drawoptions (withcolor (0,0.2,1));
+fill (55.1599,40.0898)--(113.98,37.21)--(153.94,25.8999)
+ ..controls (153.94,25.8999) and (123.42,17.8398)..(145.88,14.6699)
+ ..controls (168.34,11.4299) and (158.91,11)..(152.65,7.3999)
+ ..controls (146.31,3.7998) and (118.95,1.05981)..(113.48,1.05981)
+ ..controls (108.08,1.05981) and (35.6499,1.05981)..(35.6499,1.05981)
+ --(55.1599,40.0898)--cycle;
+drawoptions (withcolor (1,0.7,0));
+fill (146.96,157.59)--(149.77,157.59)--(149.77,118.06)
+ --(146.96,118.06)--(146.96,157.59)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (146.96,157.59)--(149.77,157.59)--(149.77,118.06)
+ --(146.96,118.06)--(146.96,157.59);
+drawoptions (withcolor (1,0.7,0));
+pickup pencircle scaled 0bp;
+fill (109.16,161.05)--(180.37,158.53)--(176.41,154.86)
+ --(108.66,157.3)--(109.16,161.05)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (109.16,161.05)--(180.37,158.53)--(176.41,154.86)
+ --(108.66,157.3)--(109.16,161.05);
+drawoptions (withcolor (1,0.9,0));
+pickup pencircle scaled 0bp;
+fill (107.65,166.74)--(192.18,162.27)--(189.94,159.54)
+ --(108.15,162.99)--(107.65,166.74)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (107.65,166.74)--(192.18,162.27)--(189.94,159.54)
+ --(108.15,162.99)--(107.65,166.74);
+drawoptions (withcolor (1,0.9,0));
+pickup pencircle scaled 0bp;
+fill (149.77,163.86)--(153.8,163.86)--(153.8,110.07)
+ --(149.77,110.07)--(149.77,163.86)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (149.77,163.86)--(153.8,163.86)--(153.8,110.07)
+ --(149.77,110.07)--(149.77,163.86);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 2.23bp;
+draw (112.26,165.3)--(104.77,109.14);
+draw (109.59,159.82)--(102.75,116.62);
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (153.73,150.61)--(163.38,129.3);
+draw (153.51,140.17)--(163.09,124.33);
+drawoptions (withcolor (0,0.2,1));
+pickup pencircle scaled 0bp;
+fill (162.58,130.74)--(168.99,130.74)--(168.99,114.9)
+ --(162.58,114.9)--(162.58,130.74)--cycle;
+drawoptions (withcolor (0,0.4,1));
+fill (153.22,123.1)--(162.58,123.1)--(162.58,115.9)
+ --(153.22,115.9)--(153.22,123.1)--cycle;
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0.86bp;
+draw (101.89,117.92)--(149.05,117.42);
+pickup pencircle scaled 2.02bp;
+draw (103.98,113.46)--(150.56,113.67);
+pickup pencircle scaled 0bp;
+fill (102.25,109.71)--(146.82,109.71)--(146.82,107.77)
+ --(102.25,107.77)--(102.25,109.71)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (102.25,109.71)--(146.82,109.71)--(146.82,107.77)
+ --(102.25,107.77)--(102.25,109.71);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (90.4399,158.02)--(92.1699,158.02)--(92.1699,117.92)
+ --(90.4399,117.92)--(90.4399,158.02)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (90.4399,158.02)--(92.1699,158.02)--(92.1699,117.92)
+ --(90.4399,117.92)--(90.4399,158.02);
+drawoptions (withcolor (0,0,0));
+draw (161.86,94.8799)--(164.1,94.8799)--(164.1,92.22)
+ --(161.86,92.22)--(161.86,94.8799);
+drawoptions (withcolor (0.8,0.3,0));
+pickup pencircle scaled 0bp;
+fill (147.32,104.1)--(149.05,104.1)--(149.05,87.97)
+ --(147.32,87.97)--(147.32,104.1)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (147.32,104.1)--(149.05,104.1)--(149.05,87.97)
+ --(147.32,87.97)--(147.32,104.1);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (148.54,104.6)--(150.27,104.6)--(150.27,87.6799)
+ --(148.54,87.6799)--(148.54,104.6)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (148.54,104.6)--(150.27,104.6)--(150.27,87.6799)
+ --(148.54,87.6799)--(148.54,104.6);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (141.2,107.55)--(147.1,107.55)--(147.1,87.25)
+ --(141.2,87.25)--(141.2,107.55)--cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0.86bp;
+draw (141.2,107.55)--(147.1,107.55)--(147.1,87.25)
+ --(141.2,87.25)--(141.2,107.55);
+drawoptions (withcolor (0,0.75,1));
+pickup pencircle scaled 0bp;
+fill (141.49,88.1799)--(153.58,88.1799)--(161.22,81.99)
+ --(143.22,81.2)--(141.49,88.1799)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (141.49,88.1799)--(153.58,88.1799)--(161.22,81.99)
+ --(143.22,81.2)--(141.49,88.1799);
+drawoptions (withcolor (1,0.4,0));
+pickup pencircle scaled 0bp;
+fill (146.53,110.22)--(165.1,110.22)--(165.1,103.09)
+ --(162.8,103.09)--(152.94,87.97)--(147.32,87.97)
+ --(146.53,110.22)--cycle;
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 0.86bp;
+draw (146.53,110.22)--(165.1,110.22)--(165.1,103.09)
+ --(162.8,103.09)--(152.94,87.97)--(147.32,87.97)
+ --(146.53,110.22);
+drawoptions (withcolor (1,0.5,0));
+pickup pencircle scaled 0bp;
+fill (285.92,78.3899)--(163.09,104.31)--(152.43,88.6899)
+ --(160.57,82.5)..controls (160.57,82.5) and (165.39,79.76)..(175.62,74.2898)
+ ..controls (185.84,68.8198) and (187.86,71.5498)..(192.61,67.45)
+ ..controls (197.36,63.3398) and (215.65,62.0498)..(215.65,62.0498)
+ --(285.63,30.6599)--(285.92,78.3899)--cycle;
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0.86bp;
+draw (285.92,78.3899)--(163.09,104.31)--(152.43,88.6899)
+ --(160.57,82.5)..controls (160.57,82.5) and (165.39,79.76)..(175.62,74.2898)
+ ..controls (185.84,68.8198) and (187.86,71.5498)..(192.61,67.45)
+ ..controls (197.36,63.3398) and (215.65,62.0498)..(215.65,62.0498)
+ --(285.63,30.6599)--(285.92,78.3899);
+drawoptions (withcolor (0.2,0.9,0.2));
+pickup pencircle scaled 0bp;
+fill (40.1799,214.47)..controls (47.6699,214.47) and (37.0198,202.59)..(40.3999,195.82)
+ ..controls (43.7798,188.98) and (41.0498,194.46)..(47.8899,187.62)
+ ..controls (54.6599,180.78) and (59.4099,178.76)..(59.4099,173.29)
+ ..controls (59.4099,167.82) and (59.4099,166.45)..(60.1299,159.61)
+ ..controls (60.7798,152.77) and (64.8098,145.93)..(65.5298,141.82)
+ ..controls (66.25,137.79) and (68.98,134.34)..(66.25,130.95)
+ ..controls (63.5098,127.57) and (62.7898,127.57)..(52.6399,127.57)
+ ..controls (42.49,127.57) and (42.49,130.3)..(33.6299,125.48)
+ ..controls (24.7798,120.73) and (25.5,116.62)..(18.6599,120.73)
+ ..controls (11.8899,124.76) and (1.65991,128.22)..(1.65991,128.22)
+ --(1.37988,214.47)--(40.1799,214.47)--cycle;
+drawoptions (withcolor (0,0.5,1));
+fill (122.41,51.8999)..controls (122.41,51.8999) and (121.76,52.47)..(120.25,49.3799)
+ ..controls (118.66,46.21) and (118.66,44.3398)..(115.86,39.9399)
+ ..controls (113.05,35.48) and (114.27,36.49)..(110.53,32.6699)
+ ..controls (106.71,28.9299) and (109.38,32.3799)..(104.34,28.9299)
+ ..controls (99.2998,25.47) and (94.2598,26.3398)..(89.7898,26.7)
+ ..controls (85.3999,26.98) and (76.6199,25.1799)..(72.8699,27.3398)
+ ..controls (69.1299,29.5798) and (67.8999,30.51)..(65.74,34.26)
+ ..controls (63.5798,38) and (63.5798,38)..(61.71,41.46)
+ ..controls (59.8398,44.9099) and (59.3398,48.5798)..(58.2598,50.3098)
+ --(54.8699,55.6399)--(122.41,51.8999)--cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 1.44bp;
+draw (122.41,51.8999)..controls (122.41,51.8999) and (121.76,52.47)..(120.25,49.3799)
+ ..controls (118.66,46.21) and (118.66,44.3398)..(115.86,39.9399)
+ ..controls (113.05,35.48) and (114.27,36.49)..(110.53,32.6699)
+ ..controls (106.71,28.9299) and (109.38,32.3799)..(104.34,28.9299)
+ ..controls (99.2998,25.47) and (94.2598,26.3398)..(89.7898,26.7)
+ ..controls (85.3999,26.98) and (76.6199,25.1799)..(72.8699,27.3398)
+ ..controls (69.1299,29.5798) and (67.8999,30.51)..(65.74,34.26)
+ ..controls (63.5798,38) and (63.5798,38)..(61.71,41.46)
+ ..controls (59.8399,44.9099) and (59.3398,48.5798)..(58.2598,50.3098)
+ --(54.8699,55.6399)--(122.41,51.8999);
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (202.04,156.87)--(200.53,112.81)--(234.87,107.26)
+ --(233.29,167.1)--(202.04,156.87);
+drawoptions (withcolor (1,0.25,0.25));
+pickup pencircle scaled 0bp;
+fill (246.9,189.63)--(223.06,177.32)--(202.76,160.26)
+ --(230.55,170.55)--(246.9,189.63)--cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0.86bp;
+draw (246.9,189.63)--(223.06,177.32)--(202.76,160.26)
+ --(230.55,170.55)--(246.9,189.63);
+drawoptions (withcolor (1,0.4,0.4));
+pickup pencircle scaled 0bp;
+fill (246.25,188.98)--(230.98,170.62)--(274.76,169.83)
+ --(246.25,188.98)--cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0.86bp;
+draw (246.25,188.98)--(230.98,170.62)--(274.76,169.83)
+ --(246.25,188.98);
+drawoptions (withcolor (0.3,1,0.3));
+pickup pencircle scaled 0bp;
+fill (255.75,122.1)..controls (252.3,122.1) and (253.02,121.45)..(248.26,125.48)
+ ..controls (243.51,129.58) and (242.79,126.2)..(239.41,135.06)
+ ..controls (236.02,143.91) and (234.01,141.18)..(234.66,148.66)
+ ..controls (235.3,156.22) and (230.62,155.5)..(236.02,163.06)
+ ..controls (241.42,170.55) and (240.13,166.45)..(245.53,174.66)
+ ..controls (251,182.79) and (250.28,185.53)..(255.03,186.9)
+ ..controls (259.78,188.26) and (258.49,194.38)..(264.61,186.9)
+ ..controls (270.66,179.41) and (271.3,174.58)..(276.06,173.94)
+ ..controls (280.88,173.29) and (282.25,175.95)..(282.25,167.82)
+ ..controls (282.25,159.61) and (282.9,154.86)..(277.5,149.38)
+ ..controls (272.02,143.91) and (267.27,145.28)..(266.55,137.07)
+ ..controls (265.9,128.86) and (266.55,124.83)..(263.17,124.11)
+ ..controls (259.78,123.39) and (255.75,122.1)..(255.75,122.1)
+ --cycle;
+drawoptions (withcolor (0.8,0.3,0));
+fill (270.66,52.47)--(276.78,52.47)--(276.78,0.629883)
+ --(270.66,0.629883)--(270.66,52.47)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (270.66,52.47)--(276.78,52.47)--(276.78,0.629898)
+ --(270.66,0.629898)--(270.66,52.47);
+drawoptions (withcolor (0.9,0,0));
+pickup pencircle scaled 0bp;
+fill (90.5798,158.02)--(92.0198,158.02)--(92.0198,152.84)
+ --(90.5798,152.84)--(90.5798,158.02)--cycle;
+fill (90.5798,147.66)--(92.0198,147.66)--(92.0198,142.47)
+ --(90.5798,142.47)--(90.5798,147.66)--cycle;
+fill (90.5798,137.43)--(92.0198,137.43)--(92.0198,132.25)
+ --(90.5798,132.25)--(90.5798,137.43)--cycle;
+fill (90.5798,128.14)--(92.0198,128.14)--(92.0198,122.96)
+ --(90.5798,122.96)--(90.5798,128.14)--cycle;
+drawoptions (withcolor (1,0.9,0));
+fill (203.34,160.98)--(200.53,160.98)--(199.38,155.29)
+ --(233.22,167.17)--(236.02,169.98)--(230.34,169.98)
+ --(203.34,160.98)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (203.34,160.98)--(200.53,160.98)--(199.38,155.29)
+ --(233.22,167.17)--(236.02,169.98)--(230.34,169.98)
+ --(203.34,160.98);
+drawoptions (withcolor (1,1,0.7));
+pickup pencircle scaled 0bp;
+fill (232.14,166.59)--(235.52,107.77)--(202.11,112.52)
+ --(202.83,155.65)--(232.14,166.59)--cycle;
+drawoptions (withcolor (0.8,0.8,0.8));
+pickup pencircle scaled 0.22bp;
+draw (232.14,166.59)--(235.52,107.77)--(202.11,112.52)
+ --(202.83,155.65)--(232.14,166.59);
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (214.42,156.3)--(214.42,145.35)--(217.81,146.07)
+ --(217.16,157.66)--(214.42,156.3);
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 1.44bp;
+draw (219.9,133.04)--(219.75,109.86)--(230.77,108.42)
+ --(230.12,133.04)--(219.9,133.04);
+drawoptions (withcolor (0,0.8,0));
+pickup pencircle scaled 0bp;
+fill (212.34,118.64)..controls (217.16,122.1) and (219.82,117.34)..(221.19,126.2)
+ ..controls (222.56,135.13) and (224.65,137.86)..(221.91,141.25)
+ ..controls (219.18,144.7) and (213.06,146.07)..(213.06,146.07)
+ ..controls (213.06,146.07) and (213.7,152.26)..(208.3,149.46)
+ ..controls (202.83,146.72) and (196.06,153.42)..(196.06,145.93)
+ ..controls (196.06,138.37) and (200.1,135.13)..(203.55,131.67)
+ ..controls (206.94,128.29) and (206.22,127.57)..(207.58,124.18)
+ ..controls (208.95,120.73) and (212.34,118.64)..(212.34,118.64)
+ --cycle;
+drawoptions (withcolor (0.6,0.3,0));
+fill (251.86,122.1)--(257.34,122.1)--(257.34,92.0698)
+ --(251.86,92.0698)--(251.86,122.1)--cycle;
+pickup pencircle scaled 0.86bp;
+draw (251.86,122.1)--(257.34,122.1)--(257.34,92.0698)
+ --(251.86,92.0698)--(251.86,122.1);
+drawoptions (withcolor (0.6,0.85,1));
+pickup pencircle scaled 0bp;
+fill (116.5,62.8398)..controls (116.5,62.8398) and (123.06,57.22)..(123.06,54.99)
+ ..controls (123.06,52.8298) and (122.98,51.25)..(118.66,49.95)
+ ..controls (114.27,48.73) and (104.62,47.7898)..(102.1,47.7898)
+ ..controls (99.5798,47.7898) and (93.3198,46.8599)..(91.45,46.8599)
+ ..controls (89.5798,46.8599) and (77.0498,46.21)..(74.5298,46.8599)
+ ..controls (72.0798,47.4299) and (65.8198,46.21)..(63.5798,47.7898)
+ ..controls (61.4199,49.3799) and (58.3298,49.95)..(56.74,52.47)
+ ..controls (55.1599,54.99) and (55.1599,55.3499)..(55.1599,58.1599)
+ ..controls (55.1599,60.97) and (59.8398,64.4199)..(59.8398,64.4199)
+ --(116.5,62.8398)--cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 1.44bp;
+draw (116.5,62.8398)..controls (116.5,62.8398) and (123.06,57.22)..(123.06,54.99)
+ ..controls (123.06,52.8298) and (122.98,51.25)..(118.66,49.95)
+ ..controls (114.27,48.73) and (104.62,47.7898)..(102.1,47.7898)
+ ..controls (99.5798,47.7898) and (93.3198,46.8599)..(91.45,46.8599)
+ ..controls (89.5798,46.8599) and (77.0498,46.21)..(74.5298,46.8599)
+ ..controls (72.0798,47.4299) and (65.8198,46.21)..(63.5798,47.7898)
+ ..controls (61.4199,49.3799) and (58.3298,49.95)..(56.74,52.47)
+ ..controls (55.1599,54.99) and (55.1599,55.3498)..(55.1599,58.1599)
+ ..controls (55.1599,60.97) and (59.8399,64.4199)..(59.8399,64.4199)
+ --(116.5,62.8398);
+drawoptions (withcolor (0.8,0.9,1));
+pickup pencircle scaled 0bp;
+fill (63.3699,81.4199)..controls (63.3699,81.4199) and (81.5098,83.5)..(87.8499,83.5)
+ ..controls (94.1799,83.5) and (111.82,82.1399)..(111.82,82.1399)
+ ..controls (111.82,82.1399) and (114.06,71.4099)..(114.06,70.0398)
+ ..controls (114.06,68.74) and (115.64,64.6399)..(115.64,64.6399)
+ --(116.29,54.6299)..controls (116.29,54.6299) and (98.5,52.5398)..(93.25,52.5398)
+ ..controls (87.99,52.5398) and (69.2698,50.5999)..(67.47,51.25)
+ ..controls (65.6699,51.8999) and (65.6699,59.8198)..(65.6699,59.8198)
+ --(63.3699,63.49)--(63.3699,81.4199)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (63.3699,81.4199)..controls (63.3699,81.4199) and (81.5098,83.5)..(87.8499,83.5)
+ ..controls (94.1799,83.5) and (111.82,82.1399)..(111.82,82.1399)
+ ..controls (111.82,82.1399) and (114.06,71.4099)..(114.06,70.0398)
+ ..controls (114.06,68.74) and (115.64,64.6399)..(115.64,64.6399)
+ --(116.29,54.6299)..controls (116.29,54.6299) and (98.5,52.5398)..(93.25,52.5398)
+ ..controls (87.99,52.5398) and (69.2698,50.5999)..(67.47,51.25)
+ ..controls (65.6699,51.8999) and (65.6699,59.8198)..(65.6699,59.8198)
+ --(63.3699,63.49)--(63.3699,81.4199);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (66.6799,78.25)..controls (68.9099,79.26) and (74.24,79.26)..(75.8198,79.26)
+ ..controls (77.3398,79.26) and (84.25,79.5398)..(84.25,79.5398)
+ --(85.1799,77.0198)--(85.1799,72.6299)--(83.5999,70.76)
+ ..controls (83.5999,70.76) and (80.22,70.76)..(77.0498,70.1099)
+ ..controls (73.8799,69.46) and (68.2598,68.5298)..(68.2598,68.5298)
+ ..controls (68.2598,68.5298) and (66.0999,69.46)..(66.0999,71.0498)
+ ..controls (66.0999,72.6299) and (66.6799,78.25)..(66.6799,78.25)
+ --cycle;
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 0.86bp;
+draw (66.6799,78.25)..controls (68.9099,79.26) and (74.24,79.26)..(75.8198,79.26)
+ ..controls (77.3398,79.26) and (84.25,79.5398)..(84.25,79.5398)
+ --(85.1799,77.0198)--(85.1799,72.6299)--(83.5999,70.76)
+ ..controls (83.5999,70.76) and (80.22,70.76)..(77.0498,70.1099)
+ ..controls (73.8799,69.46) and (68.2598,68.5298)..(68.2598,68.5298)
+ ..controls (68.2598,68.5298) and (66.0999,69.46)..(66.0999,71.0498)
+ ..controls (66.0999,72.6299) and (66.6799,78.25)..(66.6799,78.25)
+ --cycle;
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (93.0298,79.8298)--(105.85,79.5398)..controls (105.85,79.5398) and (108.37,79.26)..(108.66,77.3098)
+ ..controls (108.94,75.4399) and (109.3,72.9199)..(109.3,72.9199)
+ ..controls (109.3,72.9199) and (108.94,70.76)..(107.43,70.76)
+ ..controls (105.85,70.76) and (93.6099,70.3999)..(93.6099,70.3999)
+ ..controls (93.6099,70.3999) and (91.45,71.3398)..(91.45,72.9199)
+ ..controls (91.45,74.5) and (91.1599,77.3098)..(91.1599,77.3098)
+ --(93.0298,79.8298)--cycle;
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 0.86bp;
+draw (93.0298,79.8298)--(105.85,79.5398)..controls (105.85,79.5398) and (108.37,79.26)..(108.66,77.3098)
+ ..controls (108.94,75.4399) and (109.3,72.9199)..(109.3,72.9199)
+ ..controls (109.3,72.9199) and (108.94,70.76)..(107.43,70.76)
+ ..controls (105.85,70.76) and (93.6098,70.3999)..(93.6098,70.3999)
+ ..controls (93.6098,70.3999) and (91.45,71.3399)..(91.45,72.9199)
+ ..controls (91.45,74.5) and (91.1599,77.3098)..(91.1599,77.3098)
+ --(93.0298,79.8298);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (95.48,61.3298)..controls (98.6499,61.3298) and (108.01,61.3298)..(108.01,61.3298)
+ --(110.82,58.8098)--(110.82,56.2898)..controls (108.01,55.3499) and (96.4199,54.99)..(96.4199,54.99)
+ ..controls (96.4199,54.99) and (93.3198,54.7)..(93.3198,56.2898)
+ ..controls (93.3198,57.8699) and (93.0298,59.3799)..(93.0298,59.3799)
+ --(95.48,61.3298)--cycle;
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 0.86bp;
+draw (95.48,61.3298)..controls (98.6499,61.3298) and (108.01,61.3298)..(108.01,61.3298)
+ --(110.82,58.8098)--(110.82,56.2898)..controls (108.01,55.3499) and (96.4199,54.99)..(96.4199,54.99)
+ ..controls (96.4199,54.99) and (93.3198,54.7)..(93.3198,56.2898)
+ ..controls (93.3198,57.8699) and (93.0298,59.3799)..(93.0298,59.3799)
+ --(95.48,61.3298);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (84.5398,60.0298)--(88.2798,58.8098)--(88.2798,55.6399)
+ ..controls (88.2798,55.6399) and (88.3499,54.7)..(86.1199,54.7)
+ ..controls (83.96,54.7) and (71.72,53.1199)..(71.72,53.1199)
+ --(69.2,54.7)--(69.2,57.51)--(71.4299,59.74)
+ --(84.5398,60.0298)--cycle;
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 0.86bp;
+draw (84.5398,60.0298)--(88.2798,58.8098)--(88.2798,55.6399)
+ ..controls (88.2798,55.6399) and (88.3499,54.7)..(86.1199,54.7)
+ ..controls (83.96,54.7) and (71.72,53.1199)..(71.72,53.1199)
+ --(69.2,54.7)--(69.2,57.51)--(71.4299,59.74)
+ --(84.5398,60.0298);
+drawoptions (withcolor (0,0.7,1));
+pickup pencircle scaled 2.23bp;
+draw (65.3799,59.8198)..controls (70.6399,63.0598) and (81.22,66.6599)..(88.2798,66.4399)
+ ..controls (95.2598,66.22) and (111.97,65.2898)..(115.64,61.47);
+drawoptions (withcolor (0.4,0.8,1));
+pickup pencircle scaled 0bp;
+fill (111.82,82.1399)--(105.92,86.46)..controls (105.92,86.46) and (95.98,87.3899)..(93.8999,87.3899)
+ ..controls (91.8799,87.3899) and (81.9399,87.3899)..(81.9399,87.3899)
+ --(74.24,87.3899)--(68.3398,84.8699)--(63.5798,81.9199)
+ --(64.95,81.2)..controls (64.95,81.2) and (79.4199,83.5)..(87.3398,83.2898)
+ ..controls (95.2598,83.0698) and (111.61,82.1399)..(111.82,82.1399)
+ --cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 1.44bp;
+draw (111.82,82.1399)--(105.92,86.46)..controls (105.92,86.46) and (95.98,87.3899)..(93.8999,87.3899)
+ ..controls (91.8799,87.3899) and (81.9399,87.3899)..(81.9399,87.3899)
+ --(74.24,87.3899)--(68.3398,84.8699)--(63.5798,81.9199)
+ --(64.95,81.2)..controls (64.95,81.2) and (79.4199,83.5)..(87.3398,83.2898)
+ ..controls (95.2598,83.0698) and (111.61,82.1399)..(111.82,82.1399)
+ --cycle;
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 2.81bp;
+draw (113.84,72.8498)..controls (114.92,72.8498) and (116.29,72.8498)..(118.16,71.7)
+ ..controls (119.96,70.5398) and (119.53,70.5398)..(121.11,68.96)
+ ..controls (122.62,67.3799) and (121.98,66.22)..(121.98,66.22)
+ ..controls (121.98,66.22) and (120.82,65.5798)..(119.02,65.5798)
+ ..controls (117.22,65.5798) and (111.82,65.0698)..(109.74,65.0698)
+ ..controls (107.72,65.0698) and (103.4,65.0698)..(99.7998,65.0698)
+ ..controls (96.2,65.0698) and (90.9399,64.8599)..(88.2798,64.8599)
+ ..controls (85.5398,64.8599) and (79.4199,64.1399)..(76.47,63.9199)
+ ..controls (73.5198,63.7) and (69.49,63.7)..(66.0999,63.7)
+ ..controls (62.72,63.7) and (63.7998,62.7698)..(61.3499,64.1399)
+ ..controls (58.8298,65.5798) and (57.97,64.2099)..(57.97,66.6599)
+ ..controls (57.97,69.1799) and (56.8198,69.46)..(59.3398,71.7)
+ ..controls (61.7798,73.9299) and (61.3499,73.0598)..(63.1499,73.0598);
+pickup pencircle scaled 2.23bp;
+draw (57.97,67.0899)--(57.97,59.1699);
+draw (62.9399,62.7698)--(62.9399,51.25);
+draw (90.2998,64.8598)--(91.45,48.9399);
+draw (121.26,66.01)--(120.61,54.6299);
+draw (60.9199,72.8499)--(62,66.01);
+draw (114.7,72.5598)--(114.7,67.3799);
+pickup pencircle scaled 2.81bp;
+draw (84.6099,87.0999)--(84.8999,94.3799);
+draw (96.8498,86.46)--(96.8498,90.7798);
+drawoptions (withcolor (1,0.9,0));
+pickup pencircle scaled 0bp;
+fill (96.6299,96.25)..controls (98,96.25) and (99.1499,95.1699)..(99.1499,93.73)
+ ..controls (99.1499,92.2898) and (98,91.21)..(96.6299,91.21)
+ ..controls (95.2598,91.21) and (94.1099,92.2898)..(94.1099,93.73)
+ ..controls (94.1099,95.1699) and (95.2598,96.25)..(96.6299,96.25)
+ --cycle;
+drawoptions (withcolor (0.9,0,0));
+pickup pencircle scaled 2.23bp;
+draw (96.6299,96.25)..controls (98,96.25) and (99.1499,95.1699)..(99.1499,93.73)
+ ..controls (99.1499,92.2898) and (98,91.21)..(96.6299,91.21)
+ ..controls (95.2598,91.21) and (94.1099,92.2898)..(94.1099,93.73)
+ ..controls (94.1099,95.1699) and (95.2598,96.25)..(96.6299,96.25)
+ --cycle;
+drawoptions (withcolor (1,0.4,0));
+pickup pencircle scaled 0bp;
+fill (277.14,29.4299)--(285.99,29.4299)--(285.99,0.699951)
+ --(277.14,0.699951)--(277.14,29.4299)--cycle;
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0.86bp;
+draw (277.14,29.4299)--(285.99,29.4299)--(285.99,0.699936)
+ --(277.14,0.699936)--(277.14,29.4299);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (271.16,51.75)--(276.49,52.6199)--(276.7,49.95)
+ --(271.16,48.9399)--(271.16,51.75)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (271.16,51.75)--(276.49,52.6199)--(276.7,49.95)
+ --(271.16,48.9399)--(271.16,51.75);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (285.56,29.3599)--(285.27,32.5298)--(276.85,32.5298)
+ --(277.64,29.3599)--(285.56,29.3599)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (285.56,29.3599)--(285.27,32.5298)--(276.85,32.5298)
+ --(277.64,29.3599)--(285.56,29.3599);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (165.82,104.53)--(172.95,104.53)--(172.95,102.08)
+ --(165.82,102.08)--(165.82,104.53)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (165.82,104.53)--(172.95,104.53)--(172.95,102.08)
+ --(165.82,102.08)--(165.82,104.53);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (162.37,92.22)..controls (162.58,92.22) and (162.87,92.22)..(163.16,92.22)
+ ..controls (163.52,92.22) and (163.81,92.22)..(164.1,92.22)
+ ..controls (164.02,89.7698) and (164.02,87.3198)..(164.02,84.8699)
+ ..controls (164.02,82.3499) and (164.02,79.8999)..(164.1,77.3799)
+ ..controls (163.81,77.5298) and (163.52,77.6699)..(163.16,77.74)
+ ..controls (162.94,77.8198) and (162.58,78.0298)..(162.37,78.0298)
+ ..controls (162.3,80.4099) and (162.3,82.7798)..(162.3,85.1599)
+ ..controls (162.3,87.46) and (162.37,89.9099)..(162.37,92.22)
+ --cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (162.37,92.22)..controls (162.58,92.22) and (162.87,92.22)..(163.16,92.22)
+ ..controls (163.52,92.22) and (163.81,92.22)..(164.1,92.22)
+ ..controls (164.02,89.7698) and (164.02,87.3198)..(164.02,84.8699)
+ ..controls (164.02,82.3499) and (164.02,79.8999)..(164.1,77.3799)
+ ..controls (163.81,77.5298) and (163.52,77.6699)..(163.16,77.74)
+ ..controls (162.94,77.8198) and (162.58,78.0298)..(162.37,78.0298)
+ ..controls (162.3,80.4099) and (162.3,82.7798)..(162.3,85.1599)
+ ..controls (162.3,87.46) and (162.37,89.9099)..(162.37,92.22)
+ --cycle;
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (161.94,92.6499)--(164.31,92.6499)--(164.31,93.6599)
+ --(161.94,93.6599)--(161.94,92.6499)--cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0.86bp;
+draw (161.94,92.6499)--(164.31,92.6499)--(164.31,93.6599)
+ --(161.94,93.6599)--(161.94,92.6499);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (147.25,105.9)--(150.34,105.9)--(150.34,104.53)
+ --(147.25,104.53)--(147.25,105.9)--cycle;
+drawoptions (withcolor (0.1,0.1,0.1));
+pickup pencircle scaled 0.86bp;
+draw (147.25,105.9)--(150.34,105.9)--(150.34,104.53)
+ --(147.25,104.53)--(147.25,105.9);
+drawoptions (withcolor (0,0.7,1));
+pickup pencircle scaled 0bp;
+fill (105.85,90.6299)..controls (110.82,92.5) and (110.82,92)..(113.98,92.9399)
+ ..controls (117.08,93.7998) and (117.58,92.5)..(120.25,92.5)
+ ..controls (122.91,92.5) and (128.67,92)..(130.62,92)
+ --(135.58,92)--(141.85,93.3699)--(143.22,82.5)
+ --(154.45,82.5)--(159.78,79.3298)..controls (159.78,79.3298) and (159.34,72.1299)..(155.74,72.1299)
+ ..controls (152.22,72.1299) and (147.61,69.3899)..(144.08,72.1299)
+ ..controls (140.55,74.7898) and (136.88,75.22)..(134.22,74.7898)
+ ..controls (131.55,74.3599) and (126.94,73.9299)..(123.42,73.9299)
+ ..controls (119.82,73.9299) and (113.05,73.9299)..(113.05,73.9299)
+ --(111.25,82.9299)--(105.85,87.46)--(105.85,90.6299)
+ --cycle;
+drawoptions (withcolor (0,0.4,1));
+fill (109.88,100.93)..controls (116.22,103.45) and (119.82,103.23)..(123.85,103.66)
+ ..controls (127.95,104.1) and (132.49,104.89)..(133.35,104.6)
+ --(138.75,102.8)--(136.02,99.6299)..controls (136.02,99.6299) and (138.25,93.2998)..(136.02,95.0999)
+ ..controls (133.78,96.8999) and (130.18,96.8999)..(127.02,97.3298)
+ ..controls (123.85,97.76) and (118.45,95.5298)..(121.18,95.5298)
+ ..controls (123.85,95.5298) and (131.98,95.5298)..(134.65,94.23)
+ --(139.18,91.9299)..controls (139.18,91.9299) and (112.18,91.9299)..(108.51,91.9299)
+ ..controls (104.91,91.9299) and (104.55,96.0298)..(106.78,96.0298)
+ ..controls (109.02,96.0298) and (115.78,98.7)..(115.78,98.7)
+ --(107.65,100.06)--(109.88,100.93)--cycle;
+drawoptions (withcolor (0.6,0.3,0));
+fill (45.9399,128.07)..controls (45.9399,128.07) and (45.0798,122.6)..(45.9399,118.57)
+ ..controls (46.8799,114.54) and (45.9399,113.17)..(47.3098,110.43)
+ ..controls (48.6799,107.77) and (50.48,104.17)..(50.48,104.17)
+ --(54.9399,101.5)--(52.71,99.6299)--(47.74,99.6299)
+ --(43.21,103.3)--(41.9099,114.03)--(41.4099,123.1)
+ --(40.98,127.64)--(45.9399,128.07)--cycle;
+fill (45.0798,95.1699)..controls (45.0798,95.1699) and (42.2698,98.7)..(41.4099,101.94)
+ ..controls (40.5398,105.1) and (38.74,111.37)..(38.74,114.97)
+ ..controls (38.74,118.57) and (38.74,128.07)..(38.74,128.07)
+ --(31.5398,124.04)..controls (31.5398,124.04) and (31.0398,119.5)..(31.5398,116.34)
+ ..controls (31.98,113.17) and (32.8398,108.2)..(33.3398,105.1)
+ ..controls (33.7798,101.94) and (34.21,100.57)..(34.21,97.8298)
+ ..controls (34.21,95.1699) and (39.6799,94.23)..(39.6799,94.23)
+ --(45.0798,95.1699)--cycle;
+fill (27.9399,87.46)..controls (27.9399,87.46) and (27.5098,96.46)..(27.5098,99.2)
+ ..controls (27.5098,101.94) and (27.5098,113.17)..(27.5098,113.17)
+ --(27.0798,120.37)--(22.98,119.07)--(15.3398,123.61)
+ ..controls (15.3398,123.61) and (15.3398,113.6)..(15.3398,110.94)
+ ..controls (15.3398,108.2) and (15.7798,101.5)..(15.3398,96.97)
+ ..controls (14.9099,92.4299) and (15.7798,92)..(14.9099,88.8298)
+ ..controls (13.98,85.6599) and (21.1799,86.5298)..(21.1799,86.5298)
+ --(26.1399,85.23)--(27.9399,87.46)--cycle;
+fill (1.37988,78.3899)--(15.3398,77.5298)..controls (15.3398,77.5298) and (14.8398,80.7)..(13.5398,83.3599)
+ ..controls (12.1799,86.0999) and (7.63989,86.96)..(6.77979,92.8599)
+ ..controls (5.83984,98.7698) and (4.53979,102.8)..(4.53979,107.77)
+ ..controls (4.53979,112.74) and (4.10986,127.21)..(4.10986,127.21)
+ --(1.37988,127.64)--(1.37988,78.3899)--cycle;
+drawoptions (withcolor (0,0.75,1));
+fill (220.62,63.9199)--(217.45,58.5198)--(223.78,51.6799)
+ ..controls (223.78,51.6799) and (230.98,47.22)..(234.15,46.2798)
+ ..controls (237.32,45.3398) and (244.52,43.5398)..(244.52,43.5398)
+ --(257.12,43.5398)--(261.66,44.0498)--(267.42,42.6799)
+ --(266.55,36.3398)--(259.78,32.74)..controls (259.78,32.74) and (254.46,30.9399)..(248.98,32.74)
+ ..controls (243.58,34.5398) and (240.92,34.1099)..(236.38,34.98)
+ ..controls (231.85,35.9099) and (222.42,37.71)..(221.98,40.45)
+ ..controls (221.55,43.1099) and (219.32,49.0198)..(219.32,49.0198)
+ --(217.45,54.4199)--(218.38,62.5498)--(220.62,63.9199)
+ --cycle;
+drawoptions (withcolor (0.6,0.3,0));
+fill (219.75,63.9199)--(235.02,63.9199)..controls (235.02,63.9199) and (238.18,63.9199)..(243.15,62.1199)
+ ..controls (248.12,60.3198) and (257.12,56.22)..(257.12,56.22)
+ --(262.09,51.25)--(266.98,48.5798)--(266.98,42.6799)
+ --(260.72,44.0498)--(246.32,41.74)--(231.42,46.7798)
+ --(222.42,52.1799)--(218.82,57.1499)--(219.75,63.9199)
+ --cycle;
+drawoptions (withcolor (1,0.9,0));
+fill (223.78,55.7798)--(227.38,60.75)--(231.42,61.6899)
+ ..controls (231.42,61.6899) and (235.88,61.6899)..(238.62,61.26)
+ ..controls (241.35,60.75) and (245.38,59.3799)..(248.12,57.5798)
+ ..controls (250.78,55.7798) and (256.18,52.6199)..(256.18,52.6199)
+ --(254.89,48.5798)--(249.42,46.2798)--(243.58,48.0798)
+ --(237.75,53.0498)--(233.65,54.9199)--(223.78,55.7798)
+ --cycle;
+drawoptions (withcolor (0.4,0.4,0.4));
+fill (221.34,54.4199)--(224.65,50.3799)..controls (224.65,50.3799) and (229.62,47.6499)..(232.35,46.7798)
+ ..controls (235.02,45.8499) and (240.56,44.6199)..(240.92,44.48)
+ --(246.75,42.25)--(251.29,48.0798)--(243.58,51.25)
+ --(236.02,54.4199)--(229.18,56.22)--(221.34,54.4199)
+ --cycle;
+drawoptions (withcolor (0.8,0.8,0.8));
+fill (219.32,63.0598)--(219.32,58.0198)--(224.22,51.25)
+ ..controls (224.22,51.25) and (231.92,47.22)..(235.02,45.8499)
+ ..controls (238.18,44.48) and (243.15,43.1099)..(245.89,43.1099)
+ ..controls (248.55,43.1099) and (253.09,43.1099)..(255.75,43.1099)
+ ..controls (258.42,43.1099) and (262.02,44.0498)..(264.32,43.1099)
+ ..controls (266.55,42.25) and (267.42,40.45)..(267.42,40.45)
+ --(262.09,38.6499)..controls (262.09,38.6499) and (255.75,38.6499)..(251.65,38.6499)
+ ..controls (247.62,38.6499) and (240.92,39.51)..(237.32,40.45)
+ ..controls (233.65,41.3098) and (226.88,43.98)..(223.78,47.22)
+ ..controls (220.62,50.3799) and (218.38,53.98)..(218.38,53.98)
+ --(219.32,63.0598)--cycle;
+drawoptions (withcolor (0.6,0.3,0));
+fill (271.45,52.8999)--(271.23,1.41992)--(266.34,1.41992)
+ --(266.41,54.2)..controls (266.41,54.2) and (272.17,53.1899)..(271.45,52.8999)
+ --cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0.86bp;
+draw (271.45,52.8999)--(271.23,1.41992)--(266.34,1.41992)
+ --(266.41,54.2)..controls (266.41,54.2) and (272.17,53.1899)..(271.45,52.8999)
+ --cycle;
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (271.16,51.75)--(266.26,54.1299)--(266.26,50.8899)
+ --(271.16,48.9399)--(271.16,51.75)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (271.16,51.75)--(266.26,54.1299)--(266.26,50.8899)
+ --(271.16,48.9399)--(271.16,51.75);
+drawoptions (withcolor (0.6,0.85,1));
+pickup pencircle scaled 0bp;
+fill (121.98,48.0798)..controls (129.82,48.51) and (138.9,48.51)..(143.36,48.51)
+ ..controls (147.75,48.51) and (157.69,51.6799)..(163.52,49.0198)
+ ..controls (169.42,46.2798) and (168.99,44.0498)..(174.82,43.5398)
+ ..controls (180.66,43.1099) and (189.66,39.51)..(189.66,39.51)
+ ..controls (189.66,39.51) and (190.52,35.8398)..(193.26,34.0398)
+ ..controls (195.99,32.24) and (185.62,29.5)..(185.62,29.5)
+ --(173.89,35.8398)..controls (173.89,35.8398) and (156.32,40.8799)..(152.72,40.8799)
+ ..controls (149.12,40.8799) and (134.79,39.9399)..(134.79,39.9399)
+ ..controls (134.79,39.9399) and (130.69,34.47)..(140.19,34.0398)
+ ..controls (149.55,33.6099) and (157.69,30.9399)..(157.69,30.9399)
+ ..controls (157.69,30.9399) and (156.32,25.47)..(152.72,25.47)
+ ..controls (149.12,25.47) and (129.82,26.4099)..(125.36,26.4099)
+ ..controls (120.82,26.4099) and (103.62,28.21)..(108.51,30.9399)
+ ..controls (113.48,33.6099) and (116.79,41.3098)..(116.79,41.3098)
+ ..controls (116.79,41.3098) and (118.59,46.71)..(121.98,48.0798)
+ --cycle;
+drawoptions (withcolor (1,1,1));
+fill (266.12,54.1299)--(271.3,51.46)--(276.7,52.6199)
+ --(273.68,54.99)--(266.12,54.1299)--cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0.86bp;
+draw (266.12,54.1299)--(271.3,51.46)--(276.7,52.6199)
+ --(273.68,54.99)--(266.12,54.1299);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (189.73,159.75)--(185.05,155.07)--(176.19,155.07)
+ --(181.09,159.75)--(189.73,159.75)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (189.73,159.75)--(185.05,155.07)--(176.19,155.07)
+ --(181.09,159.75)--(189.73,159.75);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (191.24,121.45)..controls (191.24,118.71) and (191.24,115.54)..(191.24,113.89)
+ ..controls (191.24,112.16) and (191.6,109.35)..(191.24,107.91)
+ ..controls (190.81,106.54) and (190.38,105.46)..(190.38,105.46)
+ --(190.59,103.16)--(193.98,104.02)--(194.41,106.54)
+ ..controls (194.41,106.54) and (194.41,111.94)..(194.41,113.02)
+ ..controls (194.41,114.03) and (195.06,123.54)..(195.06,123.54)
+ --(191.24,121.45)--cycle;
+pickup pencircle scaled 0.86bp;
+draw (191.24,121.45)..controls (191.24,118.71) and (191.24,115.54)..(191.24,113.89)
+ ..controls (191.24,112.16) and (191.6,109.35)..(191.24,107.91)
+ ..controls (190.81,106.54) and (190.38,105.46)..(190.38,105.46)
+ --(190.59,103.16)--(193.98,104.02)--(194.41,106.54)
+ ..controls (194.41,106.54) and (194.41,111.94)..(194.41,113.02)
+ ..controls (194.41,114.03) and (195.06,123.54)..(195.06,123.54)
+ --(191.24,121.45);
+pickup pencircle scaled 0bp;
+fill (216.58,98.5498)..controls (216.58,100.21) and (216.15,99.3398)..(216.01,102.73)
+ ..controls (215.79,106.11) and (215.14,107.12)..(215.14,110.22)
+ ..controls (215.14,113.46) and (215.14,116.98)..(215.14,118.06)
+ ..controls (215.14,119.14) and (215.14,120.37)..(215.14,120.37)
+ --(212.19,119.36)..controls (212.19,119.36) and (212.19,118.71)..(212.19,116.98)
+ ..controls (212.19,115.33) and (212.19,113.17)..(212.19,111.3)
+ ..controls (212.19,109.42) and (212.19,109.5)..(212.19,106.98)
+ ..controls (212.19,104.46) and (212.05,101.94)..(212.05,101.94)
+ --(211.4,99.3398)--(213.27,98.7)--(216.58,98.5498)
+ --cycle;
+pickup pencircle scaled 0.86bp;
+draw (216.58,98.5498)..controls (216.58,100.21) and (216.15,99.3399)..(216.01,102.73)
+ ..controls (215.79,106.11) and (215.14,107.12)..(215.14,110.22)
+ ..controls (215.14,113.46) and (215.14,116.98)..(215.14,118.06)
+ ..controls (215.14,119.14) and (215.14,120.37)..(215.14,120.37)
+ --(212.19,119.36)..controls (212.19,119.36) and (212.19,118.71)..(212.19,116.98)
+ ..controls (212.19,115.33) and (212.19,113.17)..(212.19,111.3)
+ ..controls (212.19,109.42) and (212.19,109.5)..(212.19,106.98)
+ ..controls (212.19,104.46) and (212.05,101.94)..(212.05,101.94)
+ --(211.4,99.3399)--(213.27,98.6999)--(216.58,98.5498);
+pickup pencircle scaled 0bp;
+fill (184.54,108.78)--(184.54,114.46)--(183.46,116.19)
+ --(182.67,114.46)..controls (182.67,114.46) and (182.82,113.24)..(182.82,112.16)
+ ..controls (182.82,111.08) and (182.82,109.64)..(182.82,109.64)
+ --(184.54,108.78)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (184.54,108.78)--(184.54,114.46)--(183.46,116.19)
+ --(182.67,114.46)..controls (182.67,114.46) and (182.82,113.24)..(182.82,112.16)
+ ..controls (182.82,111.08) and (182.82,109.64)..(182.82,109.64)
+ --(184.54,108.78);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (178.28,117.85)..controls (178.28,117.85) and (178.42,115.76)..(178.42,114.68)
+ ..controls (178.42,113.6) and (178.42,111.3)..(178.42,111.3)
+ --(176.98,109.64)--(176.98,113.46)--(176.98,116.55)
+ --(178.28,117.85)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (178.28,117.85)..controls (178.28,117.85) and (178.42,115.76)..(178.42,114.68)
+ ..controls (178.42,113.6) and (178.42,111.3)..(178.42,111.3)
+ --(176.98,109.64)--(176.98,113.46)--(176.98,116.55)
+ --(178.28,117.85);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (180.51,109.21)..controls (180.51,109.21) and (180.3,109.5)..(180.51,112.16)
+ ..controls (180.73,114.9) and (180.73,117.85)..(180.73,117.85)
+ --(179.5,118.06)..controls (179.5,118.06) and (179.5,115.9)..(179.5,114.9)
+ ..controls (179.5,113.89) and (179.29,110.86)..(179.29,110.86)
+ --(179.5,108.99)--(180.51,109.21)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (180.51,109.21)..controls (180.51,109.21) and (180.3,109.5)..(180.51,112.16)
+ ..controls (180.73,114.9) and (180.73,117.85)..(180.73,117.85)
+ --(179.5,118.06)..controls (179.5,118.06) and (179.5,115.9)..(179.5,114.9)
+ ..controls (179.5,113.89) and (179.29,110.86)..(179.29,110.86)
+ --(179.5,108.99)--(180.51,109.21);
+drawoptions (withcolor (0,0.5,0));
+pickup pencircle scaled 0bp;
+fill (192.46,150.97)..controls (185.55,150.54) and (182.6,151.98)..(182.38,148.88)
+ ..controls (182.24,145.71) and (184.54,150.97)..(185.34,145.28)
+ ..controls (186.2,139.59) and (186.85,138.51)..(186.85,136.21)
+ ..controls (186.85,133.9) and (188.86,133.9)..(189.3,136.42)
+ ..controls (189.73,138.94) and (190.02,140.89)..(192.1,142.11)
+ ..controls (194.19,143.41) and (195.06,146.94)..(191.46,146.5)
+ ..controls (187.86,146.14) and (190.59,149.89)..(190.59,149.89)
+ --(192.46,150.97)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (221.77,159.61)--(227.17,163.06)--(226.52,146.65)
+ --(222.42,145.93)--(221.77,159.61);
+draw (207.8,155.43)--(205.28,153.92)--(205.28,149.1);
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 1.44bp;
+draw (204.63,125.48)--(204.63,118.28)--(209.24,117.63);
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (224,160.9)--(224.14,148.88);
+draw (222.06,154.78)--(226.88,157.09);
+draw (216.01,151.62)--(215.79,145.71);
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 1.44bp;
+draw (223.5,130.52)--(227.96,130.52)--(228.18,124.4);
+draw (222.7,118.28)--(222.7,115.76)--(228.39,115.11);
+draw (222.27,123.32)--(227.53,123.18);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (240.42,126.27)--(236.82,126.7)--(236.82,113.17)
+ --(241.35,113.17)--(240.42,126.27)--cycle;
+drawoptions (withcolor (0.5,0.5,0.5));
+pickup pencircle scaled 0.22bp;
+draw (240.42,126.27)--(236.82,126.7)--(236.82,113.17)
+ --(241.35,113.17)--(240.42,126.27);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (246.75,126.7)--(242.65,126.7)--(243.58,112.23)
+ --(248.12,111.8)--(248.55,119.07)--(246.75,126.7)
+ --cycle;
+drawoptions (withcolor (0.5,0.5,0.5));
+pickup pencircle scaled 0.22bp;
+draw (246.75,126.7)--(242.65,126.7)--(243.58,112.23)
+ --(248.12,111.8)--(248.55,119.07)--(246.75,126.7);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (258.7,119.79)--(258.7,111.66)--(262.74,111.66)
+ --(263.24,123.82)--(258.27,122.96)--(258.7,119.79)
+ --cycle;
+drawoptions (withcolor (0.5,0.5,0.5));
+pickup pencircle scaled 0.22bp;
+draw (258.7,119.79)--(258.7,111.66)--(262.74,111.66)
+ --(263.24,123.82)--(258.27,122.96)--(258.7,119.79);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (269.36,126.49)--(264.82,126.49)--(265.33,110.22)
+ --(270.73,110.22)--(269.36,126.49)--cycle;
+drawoptions (withcolor (0.5,0.5,0.5));
+pickup pencircle scaled 0.22bp;
+draw (269.36,126.49)--(264.82,126.49)--(265.33,110.22)
+ --(270.73,110.22)--(269.36,126.49);
+drawoptions (withcolor (1,0.8,0.8));
+pickup pencircle scaled 0bp;
+fill (273.32,101.5)--(285.92,98.26)--(285.92,156.58)
+ --(273.32,145.28)--(273.32,101.5)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (273.32,101.5)--(285.92,98.26)--(285.92,156.58)
+ --(273.32,145.28)--(273.32,101.5);
+drawoptions (withcolor (0.95,0.95,0.95));
+pickup pencircle scaled 0bp;
+fill (277.86,125.41)--(276.92,109.57)--(285.92,107.77)
+ --(285.49,123.61)--(277.86,125.41)--cycle;
+drawoptions (withcolor (0.6,0.6,0.6));
+pickup pencircle scaled 1.44bp;
+draw (277.86,125.41)--(276.92,109.57)--(285.92,107.77)
+ --(285.49,123.61)--(277.86,125.41);
+drawoptions (withcolor (0.9,0.9,0.9));
+pickup pencircle scaled 0bp;
+fill (278.29,125.84)--(285.49,123.61)--(285.92,131.24)
+ --(278.29,132.18)--(278.29,125.84)--cycle;
+drawoptions (withcolor (0.6,0.6,0.6));
+pickup pencircle scaled 1.44bp;
+draw (278.29,125.84)--(285.49,123.61)--(285.92,131.24)
+ --(278.29,132.18)--(278.29,125.84);
+pickup pencircle scaled 0.86bp;
+draw (237.32,121.3)--(240.42,121.3);
+drawoptions (withcolor (0.5,0.5,0.5));
+draw (243.15,121.3)--(248.12,120.87);
+draw (259.35,120.37)--(262.52,119.94);
+draw (265.69,121.3)--(269.22,120.87);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (166.04,101.86)..controls (167.12,101.94) and (168.2,101.94)..(169.35,101.94)
+ ..controls (170.43,101.94) and (171.51,101.94)..(172.74,101.86)
+ ..controls (172.66,97.5398) and (172.66,93.1499)..(172.66,88.76)
+ ..controls (172.66,84.3699) and (172.66,79.98)..(172.74,75.5798)
+ ..controls (171.51,76.0898) and (170.43,76.5898)..(169.35,77.0198)
+ ..controls (168.27,77.46) and (167.12,77.96)..(166.04,78.3198)
+ ..controls (166.04,82.2798) and (166.04,86.1699)..(166.04,90.1299)
+ ..controls (166.04,94.0198) and (166.04,97.98)..(166.04,101.86)
+ --cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0.86bp;
+draw (166.04,101.86)..controls (167.12,101.94) and (168.2,101.94)..(169.35,101.94)
+ ..controls (170.43,101.94) and (171.51,101.94)..(172.74,101.86)
+ ..controls (172.66,97.5398) and (172.66,93.1499)..(172.66,88.76)
+ ..controls (172.66,84.3699) and (172.66,79.98)..(172.74,75.5798)
+ ..controls (171.51,76.0899) and (170.43,76.5898)..(169.35,77.0198)
+ ..controls (168.27,77.4599) and (167.12,77.9599)..(166.04,78.3198)
+ ..controls (166.04,82.2798) and (166.04,86.1699)..(166.04,90.1299)
+ ..controls (166.04,94.0198) and (166.04,97.98)..(166.04,101.86)
+ --cycle;
+drawoptions (withcolor (0,0.6,0));
+pickup pencircle scaled 0bp;
+fill (25.21,151.54)..controls (35.4299,157.66) and (33.3398,161.05)..(32.7,169.33)
+ ..controls (32.0498,177.54) and (29.3098,183.01)..(30.6799,189.13)
+ ..controls (32.0498,195.32) and (25.9299,187.04)..(23.8398,181.57)
+ ..controls (21.8198,176.17) and (13.6199,171.34)..(13.6199,171.34)
+ ..controls (13.6199,171.34) and (5.47998,167.89)..(8.85986,179.55)
+ ..controls (12.25,191.22) and (5.47998,189.78)..(5.47998,185.02)
+ ..controls (5.47998,180.27) and (3.38989,170.62)..(5.47998,164.5)
+ ..controls (7.5,158.38) and (12.3198,157.66)..(12.97,161.05)
+ ..controls (13.6199,164.5) and (17.0698,159.68)..(17.0698,152.19)
+ ..controls (17.0698,144.7) and (25.21,151.54)..(25.21,151.54)
+ --cycle;
+fill (38.8198,143.98)..controls (44.2898,150.18) and (44.2898,155)..(44.2898,159.75)
+ ..controls (44.2898,164.5) and (43.5698,178.18)..(46.2998,174.73)
+ ..controls (49.0398,171.34) and (53.7898,163.86)..(53.7898,158.38)
+ ..controls (53.7898,152.91) and (46.3799,148.09)..(51.1299,143.98)
+ ..controls (55.8799,139.88) and (59.2598,136.5)..(50.4099,136.5)
+ ..controls (41.5498,136.5) and (34.0598,134.41)..(34.0598,134.41)
+ --(38.8198,143.98)--cycle;
+drawoptions (withcolor (0,0.8,0));
+fill (254.6,137.86)..controls (254.6,145.42) and (251.14,148.16)..(254.6,155)
+ ..controls (257.98,161.84) and (261.44,170.7)..(261.44,170.7)
+ ..controls (261.44,170.7) and (262.74,170.7)..(262.74,165.94)
+ ..controls (262.74,161.12) and (268.93,156.3)..(268.93,156.3)
+ --(269.58,149.46)--(262.09,141.97)..controls (262.09,141.97) and (262.09,139.23)..(262.09,134.48)
+ ..controls (262.09,129.66) and (254.6,137.86)..(254.6,137.86)
+ --cycle;
+drawoptions (withcolor (0.95,0.95,0.95));
+fill (80.3599,197.34)..controls (117.8,197.34) and (98.0698,202.81)..(123.92,202.81)
+ ..controls (149.77,202.81) and (150.42,203.53)..(162.66,200.79)
+ ..controls (174.97,198.06) and (174.25,195.25)..(185.84,193.23)
+ ..controls (197.43,191.22) and (206.29,189.78)..(204.92,185.02)
+ ..controls (203.55,180.27) and (180.44,174.15)..(174.97,176.82)
+ ..controls (169.5,179.55) and (155.17,184.38)..(150.42,184.38)
+ ..controls (145.66,184.38) and (110.31,192.58)..(110.31,192.58)
+ ..controls (110.31,192.58) and (102.82,188.41)..(115.14,185.74)
+ ..controls (127.38,183.01) and (154.52,178.9)..(142.28,172.71)
+ ..controls (130.04,166.52) and (115.78,176.17)..(106.93,176.17)
+ ..controls (98.0698,176.17) and (85.1799,176.82)..(78.99,179.55)
+ ..controls (72.8699,182.29) and (61.2798,190.5)..(54.5098,193.95)
+ ..controls (47.6699,197.34) and (49.6899,205.54)..(59.2598,204.18)
+ ..controls (68.7698,202.81) and (80.3599,197.34)..(80.3599,197.34)
+ --cycle;
+drawoptions (withcolor (1,0.4,0));
+fill (14.3398,40.8098)..controls (21.8198,45.5598) and (32.7,53.0498)..(34.7798,56.5)
+ ..controls (36.7998,59.8899) and (37.45,49.6599)..(37.45,49.6599)
+ --(45.6599,57.1499)--(45.6599,47.6499)..controls (45.6599,47.6499) and (42.2,42.8198)..(39.5398,38)
+ ..controls (36.7998,33.25) and (22.47,18.2)..(22.47,18.2)
+ --(19.8098,25.0398)--(25.21,34.6199)--(23.8398,41.46)
+ --(12.25,35.26)--(14.3398,40.8098)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+fill (257.98,96.1799)--(278.43,94.8098)--(264.18,92.72)
+ --(255.25,92.72)--(257.98,96.1799)--cycle;
+drawoptions (withcolor (0.4,0.4,0.4));
+fill (215.14,102.37)..controls (215.14,102.37) and (217.16,100.28)..(220.54,100.28)
+ ..controls (224,100.28) and (230.77,99.5598)..(230.77,99.5598)
+ --(227.31,98.1899)--(215.79,97.5398)--(215.14,102.37)
+ --cycle;
+fill (193.98,104.38)--(204.92,104.38)--(203.55,100.93)
+ --(193.33,102.37)--(193.98,104.38)--cycle;
+drawoptions (withcolor (0,0.5,1));
+fill (266.12,11.8599)..controls (260.65,15.25) and (251.79,18.7)..(246.32,18.7)
+ ..controls (240.85,18.7) and (239.48,17.3398)..(230.62,17.3398)
+ ..controls (221.7,17.3398) and (212.91,15.97)..(206.07,17.3398)
+ ..controls (199.23,18.7) and (191.74,16.6199)..(186.92,16.6199)
+ ..controls (182.17,16.6199) and (183.54,11.1399)..(178.06,10.5)
+ ..controls (172.59,9.77979) and (171.94,5.66992)..(167.84,5.66992)
+ ..controls (163.74,5.66992) and (159.06,0.849854)..(168.49,0.849854)
+ ..controls (177.92,0.849854) and (266.12,0.699951)..(266.12,1.41992)
+ --(266.12,11.8599)--cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (1.01978,215.34)--(286.28,215.34)--(286.28,0.849854)
+ --(1.01978,0.849854)--(1.01978,215.34);
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (286.28,31.6599)--(280.81,35.8398)--(277.42,35.8398)
+ --(277.42,31.6599)--(286.28,31.6599)--cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.86bp;
+draw (286.28,31.6599)--(280.81,35.8398)--(277.42,35.8398)
+ --(277.42,31.6599)--(286.28,31.6599);
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 2.81bp;
+draw (69.2698,192.73)..controls (74.74,190.71) and (75.46,185.89)..(75.46,185.89)
+ --(81.5798,185.24);
+draw (62.1399,178.62)..controls (67.5398,176.6) and (69.7,176.89)..(69.7,176.89)
+ --(72.4399,180.27);
+draw (52.3499,196.11)..controls (57.8198,194.02) and (58.47,189.27)..(58.47,189.27)
+ --(61.21,192.66);
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 2.23bp;
+draw (173.17,30.73)..controls (173.17,29.72) and (173.38,28.5)..(173.38,28.5)
+ --(175.18,29.0698);
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0bp;
+fill (168.99,32.74)..controls (170.5,34.3999) and (171.51,33.1799)..(172.88,32.5298)
+ ..controls (174.25,31.8799) and (175.98,32.3098)..(175.11,31.23)
+ ..controls (174.32,30.22) and (168.56,29.3599)..(168.56,29.6499)
+ --(168.63,30.9399)--(168.13,31.6599)--(168.99,32.74)
+ --cycle;
+pickup pencircle scaled 2.23bp;
+draw (173.24,32.3098)..controls (173.24,33.3198) and (173.46,34.5398)..(173.46,34.5398)
+ --(175.33,33.97);
+drawoptions (withcolor (0,0,0));
+draw (184.33,24.3899)..controls (184.33,23.3799) and (184.54,22.1599)..(184.54,22.1599)
+ --(186.42,22.8098);
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0bp;
+fill (180.22,26.4099)..controls (181.74,28.0598) and (182.67,26.8398)..(184.04,26.1899)
+ ..controls (185.41,25.5398) and (187.14,25.98)..(186.34,24.97)
+ ..controls (185.55,23.8899) and (179.72,23.0198)..(179.72,23.3098)
+ --(179.86,24.6099)--(179.29,25.3999)--(180.22,26.4099)
+ --cycle;
+pickup pencircle scaled 2.23bp;
+draw (184.47,25.98)..controls (184.47,26.98) and (184.69,28.21)..(184.69,28.21)
+ --(186.56,27.6299);
+drawoptions (withcolor (0,0,0));
+draw (195.7,34.8298)..controls (195.7,33.75) and (195.92,32.5298)..(195.92,32.5298)
+ --(197.79,33.1799);
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0bp;
+fill (191.6,36.7798)..controls (193.04,38.5) and (194.05,37.2798)..(195.42,36.6299)
+ ..controls (196.78,35.9099) and (198.51,36.3398)..(197.72,35.3398)
+ ..controls (196.86,34.3298) and (191.1,33.46)..(191.1,33.6799)
+ --(191.24,35.0498)--(190.66,35.7698)--(191.6,36.7798)
+ --cycle;
+pickup pencircle scaled 2.23bp;
+draw (195.85,36.3398)..controls (195.85,37.4199) and (196.06,38.6499)..(196.06,38.6499)
+ --(197.94,38);
+drawoptions (withcolor (0,0,0));
+draw (198.44,26.26)..controls (198.44,25.1799) and (198.66,23.96)..(198.66,23.96)
+ --(200.53,24.6099);
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0bp;
+fill (194.34,28.21)..controls (195.85,29.9399) and (196.78,28.71)..(198.15,28.0598)
+ ..controls (199.52,27.3398) and (201.25,27.7798)..(200.46,26.7698)
+ ..controls (199.66,25.76) and (193.83,24.8999)..(193.83,25.1099)
+ --(193.98,26.48)--(193.4,27.2)--(194.34,28.21)
+ --cycle;
+pickup pencircle scaled 2.23bp;
+draw (198.58,27.7798)..controls (198.58,28.8599) and (198.8,30.0798)..(198.8,30.0798)
+ --(200.67,29.4299);
+drawoptions (withcolor (0,0,0));
+draw (157.47,21.0798)..controls (157.47,20) and (157.76,18.7798)..(157.76,18.7798)
+ --(159.56,19.4199);
+drawoptions (withcolor (0.2,0.2,0.2));
+pickup pencircle scaled 0bp;
+fill (153.37,23.0198)..controls (154.88,24.75) and (155.82,23.5298)..(157.18,22.8799)
+ ..controls (158.62,22.1599) and (160.35,22.5898)..(159.49,21.5798)
+ ..controls (158.7,20.5798) and (152.86,19.71)..(152.86,19.9299)
+ --(153.01,21.2998)--(152.43,22.0198)--(153.37,23.0198)
+ --cycle;
+pickup pencircle scaled 2.23bp;
+draw (157.62,22.5899)..controls (157.62,23.6699) and (157.83,24.8999)..(157.83,24.8999)
+ --(159.7,24.25);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0.86bp;
+draw (114.85,113.6)--(114.85,109.71);
+draw (124.64,113.6)--(124.64,109.28);
+draw (135.01,113.46)--(135.01,109.93);
+draw (144.08,113.46)--(144.08,110.07);
+pickup pencircle scaled 0bp;
+fill (191.38,89.98)--(212.55,83.7898)--(212.55,78.3198)
+ --(219.39,72.1299)--(218.02,67.3799)--(204.34,74.22)
+ --(205.06,80.3398)--(192.1,85.8799)--(191.38,89.98)
+ --cycle;
+fill (275.98,73.5)--(263.02,76.95)--(258.27,71.48)
+ --(250.06,72.8499)--(248.7,67.3799)--(261.01,65.2898)
+ --(267.13,71.48)--(275.98,68.0999)--(275.98,73.5)
+ --cycle;
+drawoptions (withcolor (0.4,0.4,0.4));
+pickup pencircle scaled 0.86bp;
+draw (69.2698,75.5798)--(75.46,76.95);
+drawoptions (withcolor (0.3,0.3,0.3));
+draw (98.8599,77.6699)--(105.92,76.5198);
+drawoptions (withcolor (0.5,0.5,0.5));
+draw (72.9399,74.1399)--(76.3999,74.6499);
+drawoptions (withcolor (0.4,0.4,0.4));
+draw (101.17,75.4399)--(105.63,74.5);
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (15.0598,62.3398)--(16.5698,62.3398)..controls (17.0698,62.3398) and (17.4299,62.7)..(17.4299,63.2)
+ --(17.4299,67.8799)..controls (17.4299,68.3799) and (17.0698,68.74)..(16.5698,68.74)
+ --(15.0598,68.74)..controls (14.5498,68.74) and (14.1899,68.3799)..(14.1899,67.8799)
+ --(14.1899,63.2)..controls (14.1899,62.7) and (14.5498,62.3398)..(15.0598,62.3398)
+ --cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (15.0598,62.3399)--(16.5698,62.3399)..controls (17.0698,62.3399) and (17.4299,62.7)..(17.4299,63.2)
+ --(17.4299,67.8799)..controls (17.4299,68.3799) and (17.0698,68.74)..(16.5698,68.74)
+ --(15.0598,68.74)..controls (14.5498,68.74) and (14.1899,68.3799)..(14.1899,67.8799)
+ --(14.1899,63.2)..controls (14.1899,62.7) and (14.5498,62.3399)..(15.0598,62.3399)
+ --cycle;
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (13.3298,70.1099)--(18.0098,70.1099)..controls (18.5798,70.1099) and (19.0198,69.6799)..(19.0198,69.1799)
+ --(19.0198,67.95)..controls (19.0198,67.45) and (18.5798,67.0198)..(18.0098,67.0198)
+ --(13.3298,67.0198)..controls (12.75,67.0198) and (12.3198,67.45)..(12.3198,67.95)
+ --(12.3198,69.1799)..controls (12.3198,69.6799) and (12.75,70.1099)..(13.3298,70.1099)
+ --cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 1.44bp;
+draw (13.3298,70.1098)--(18.0098,70.1098)..controls (18.5798,70.1098) and (19.0198,69.6799)..(19.0198,69.1799)
+ --(19.0198,67.9499)..controls (19.0198,67.45) and (18.5798,67.0198)..(18.0098,67.0198)
+ --(13.3298,67.0198)..controls (12.75,67.0198) and (12.3198,67.45)..(12.3198,67.9499)
+ --(12.3198,69.1799)..controls (12.3198,69.6799) and (12.75,70.1098)..(13.3298,70.1098)
+ --cycle;
+drawoptions (withcolor (0.9,0.95,1));
+pickup pencircle scaled 0bp;
+fill (62.3599,49.45)--(63.22,49.45)..controls (63.5098,49.45) and (63.73,49.6599)..(63.73,49.95)
+ --(63.73,52.76)..controls (63.73,53.0498) and (63.5098,53.26)..(63.22,53.26)
+ --(62.3599,53.26)..controls (62,53.26) and (61.8599,53.0498)..(61.8599,52.76)
+ --(61.8599,49.95)..controls (61.8599,49.6599) and (62,49.45)..(62.3599,49.45)
+ --cycle;
+drawoptions (withcolor (0,0.2,1));
+pickup pencircle scaled 0.86bp;
+draw (62.3599,49.45)--(63.22,49.45)..controls (63.5098,49.45) and (63.73,49.6599)..(63.73,49.95)
+ --(63.73,52.76)..controls (63.73,53.0498) and (63.5098,53.26)..(63.22,53.26)
+ --(62.3599,53.26)..controls (62,53.26) and (61.8599,53.0498)..(61.8599,52.76)
+ --(61.8599,49.95)..controls (61.8599,49.6599) and (62,49.45)..(62.3599,49.45)
+ --cycle;
+drawoptions (withcolor (0.9,0.95,1));
+pickup pencircle scaled 0bp;
+fill (61.3499,54.0598)--(64.0898,54.0598)..controls (64.3799,54.0598) and (64.6599,53.8398)..(64.6599,53.48)
+ --(64.6599,52.8298)..controls (64.6599,52.47) and (64.3799,52.1799)..(64.0898,52.1799)
+ --(61.3499,52.1799)..controls (60.99,52.1799) and (60.7,52.47)..(60.7,52.8298)
+ --(60.7,53.48)..controls (60.7,53.8398) and (60.99,54.0598)..(61.3499,54.0598)
+ --cycle;
+drawoptions (withcolor (0,0.2,1));
+pickup pencircle scaled 1.44bp;
+draw (61.3499,54.0598)--(64.0899,54.0598)..controls (64.3799,54.0598) and (64.6599,53.8398)..(64.6599,53.48)
+ --(64.6599,52.8298)..controls (64.6599,52.47) and (64.3799,52.1799)..(64.0899,52.1799)
+ --(61.3499,52.1799)..controls (60.99,52.1799) and (60.7,52.47)..(60.7,52.8298)
+ --(60.7,53.48)..controls (60.7,53.8398) and (60.99,54.0598)..(61.3499,54.0598)
+ --cycle;
+drawoptions (withcolor (0.9,0.95,1));
+pickup pencircle scaled 0bp;
+fill (118.74,51.46)--(119.6,51.46)..controls (119.89,51.46) and (120.1,51.6099)..(120.1,51.97)
+ --(120.1,54.7)..controls (120.1,54.99) and (119.89,55.21)..(119.6,55.21)
+ --(118.74,55.21)..controls (118.38,55.21) and (118.23,54.99)..(118.23,54.7)
+ --(118.23,51.97)..controls (118.23,51.6099) and (118.38,51.46)..(118.74,51.46)
+ --cycle;
+drawoptions (withcolor (0,0.2,1));
+pickup pencircle scaled 0.86bp;
+draw (118.74,51.46)--(119.6,51.46)..controls (119.89,51.46) and (120.1,51.6098)..(120.1,51.97)
+ --(120.1,54.7)..controls (120.1,54.99) and (119.89,55.21)..(119.6,55.21)
+ --(118.74,55.21)..controls (118.38,55.21) and (118.23,54.99)..(118.23,54.7)
+ --(118.23,51.97)..controls (118.23,51.6098) and (118.38,51.46)..(118.74,51.46)
+ --cycle;
+drawoptions (withcolor (0.9,0.95,1));
+pickup pencircle scaled 0bp;
+fill (117.73,56)--(120.46,56)..controls (120.75,56) and (120.97,55.7798)..(120.97,55.4199)
+ --(120.97,54.7798)..controls (120.97,54.49) and (120.75,54.2)..(120.46,54.2)
+ --(117.73,54.2)..controls (117.37,54.2) and (117.08,54.49)..(117.08,54.7798)
+ --(117.08,55.4199)..controls (117.08,55.7798) and (117.37,56)..(117.73,56)
+ --cycle;
+drawoptions (withcolor (0,0.2,1));
+pickup pencircle scaled 1.44bp;
+draw (117.73,56)--(120.46,56)..controls (120.75,56) and (120.97,55.7798)..(120.97,55.4199)
+ --(120.97,54.7798)..controls (120.97,54.49) and (120.75,54.2)..(120.46,54.2)
+ --(117.73,54.2)..controls (117.37,54.2) and (117.08,54.49)..(117.08,54.7798)
+ --(117.08,55.4199)..controls (117.08,55.7798) and (117.37,56)..(117.73,56)
+ --cycle;
+drawoptions (withcolor (0.6,0.3,0));
+pickup pencircle scaled 0bp;
+fill (51.7,90.3398)--(52.7798,90.3398)..controls (53.1399,90.3398) and (53.3599,90.6299)..(53.3599,90.99)
+ --(53.3599,94.2998)..controls (53.3599,94.6599) and (53.1399,94.8799)..(52.7798,94.8799)
+ --(51.7,94.8799)..controls (51.3398,94.8799) and (51.1299,94.6599)..(51.1299,94.2998)
+ --(51.1299,90.99)..controls (51.1299,90.6299) and (51.3398,90.3398)..(51.7,90.3398)
+ --cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 0.86bp;
+draw (51.7,90.3399)--(52.7798,90.3399)..controls (53.1399,90.3399) and (53.3599,90.6299)..(53.3599,90.99)
+ --(53.3599,94.2998)..controls (53.3599,94.6599) and (53.1399,94.8799)..(52.7798,94.8799)
+ --(51.7,94.8799)..controls (51.3398,94.8799) and (51.1299,94.6599)..(51.1299,94.2998)
+ --(51.1299,90.99)..controls (51.1299,90.6299) and (51.3398,90.3399)..(51.7,90.3399)
+ --cycle;
+drawoptions (withcolor (1,1,1));
+pickup pencircle scaled 0bp;
+fill (50.48,95.8899)--(53.7898,95.8899)..controls (54.22,95.8899) and (54.5098,95.5999)..(54.5098,95.24)
+ --(54.5098,94.3799)..controls (54.5098,93.9399) and (54.22,93.6599)..(53.7898,93.6599)
+ --(50.48,93.6599)..controls (50.1199,93.6599) and (49.8298,93.9399)..(49.8298,94.3799)
+ --(49.8298,95.24)..controls (49.8298,95.5999) and (50.1199,95.8899)..(50.48,95.8899)
+ --cycle;
+drawoptions (withcolor (0.3,0.3,0.3));
+pickup pencircle scaled 1.44bp;
+draw (50.48,95.8899)--(53.7898,95.8899)..controls (54.22,95.8899) and (54.5098,95.5998)..(54.5098,95.24)
+ --(54.5098,94.3799)..controls (54.5098,93.9399) and (54.22,93.6599)..(53.7898,93.6599)
+ --(50.48,93.6599)..controls (50.1199,93.6599) and (49.8298,93.9399)..(49.8298,94.3799)
+ --(49.8298,95.24)..controls (49.8298,95.5998) and (50.1199,95.8899)..(50.48,95.8899)
+ --cycle;
+drawoptions (withcolor (0.2,0.2,0.2));
+draw (53,92.6499)..controls (53,88.8298) and (55.2998,80.4099)..(57.5398,76.8799)
+ ..controls (59.7698,73.3498) and (63.5798,67.8799)..(63.5798,67.8799);
+pickup pencircle scaled 2.02bp;
+draw (63.1499,52.26)..controls (63.1499,52.26) and (57.0298,49.5198)..(41.98,52.98)
+ ..controls (26.9399,56.3599) and (16.8599,66.01)..(15.8498,66.2998);
+drawoptions (withcolor (0.9,0,0));
+pickup pencircle scaled 0bp;
+fill (87.7,123.46)--(94.5398,123.46)--(94.5398,113.89)
+ --(87.7,113.89)--(87.7,123.46)--cycle;
+endfig;
+end
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-basics.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-basics.tex
index a52c7a35a63..479f396022b 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-basics.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-basics.tex
@@ -51,8 +51,8 @@ wish, your comments, your grocery list, whatever. Comments in \METAPOST, prefixe
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:
+Traditionally, if the file is saved as \type {yourfile.mp}, then the file is
+processed by \METAPOST\ by issuing the following command:
\starttyping
mpost yourfile
@@ -88,7 +88,7 @@ If you have installed \CONTEXT, somewhere on your system there resides a file
following line at the top of your file:
\starttyping
-input mp-tool ; % or input metafun ;
+input metafun ;
\stoptyping
By loading this file, the resulting graphic will provide a high resolution
@@ -96,10 +96,44 @@ 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.
+{\bf However!} When you use \METAPOST\ in \CONTEXT, you will not run the
+mentioned program at all: you embed your graphic in the document and we will
+discuss this later. You can still use separate files but then you process them as
+follows:
+
+\starttyping
+mtxrun --script metapost somefile.mp
+\stoptyping
+
+Alternatively you can wrap the individual pictures in a \TEX\ file, say \type
+{yourfile.tex}:
+
+\starttyping
+\starttext
+ \startMPpage
+ % code
+ \stopMPpage
+ \startMPpage
+ % code
+ \stopMPpage
+\stoptext
+\stoptyping
+
+and then run:
+
+\starttyping
+context somefile.tex
+\stoptyping
+
+after which you can use the resulting \PDF\ file (if it has more pages you just
+filter the page from that file).
+
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.
+you use \CONTEXT\ you don't need them at all. You can for instance wrap them in a
+\type {\startMPpage} \unknown\ \type {\stopMPpage} environment if you want to
+play around.
\startbuffer
pickup pencircle scaled .5cm ;
@@ -463,7 +497,7 @@ draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
You can consider the \type {boundingcircle} to be a round boundingbox.
-\startlinecorrection
+\startlinecorrection[blank]
\startcombination[nx=3,ny=1,location=middle]
{\processMPbuffer[a]} {square}
{\processMPbuffer[b]} {circle}
@@ -776,9 +810,9 @@ draw
{\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.
+of curves. Both \METAFONT\ and \METAPOST\ implement Bézier curves. The fact that
+these curves are named after Pierre Bézier obscures the fact that the math behind
+them originates with Sergeĭ Bernshteĭn.
The points on the curve are determined by the following formula:
@@ -2875,6 +2909,20 @@ 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.
+Here is another example:
+
+\startbuffer
+eofill for i=1 upto 12: fullcircle scaled ((i/12)*cm) -- endfor cycle ;
+\stopbuffer
+
+\typebuffer
+
+The successive larger circle are unfilled and basically form one path:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
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:
@@ -3363,7 +3411,43 @@ context("%3!texexp!", 10.4698E30,"@2.3f","@2i")
\typebuffer
-This gives: \inlinebuffer .
+This gives: \inlinebuffer . In \in {figure} [fig:formatters] we see some more
+formatters.
+
+\startbuffer
+for i=1 upto 12 :
+ draw
+ thefmttext("\letterpercent 3!date!","month,space,year",2019,i)
+ shifted (0,i *cm / 2);
+ draw
+ thefmttext("@3!date!","month,space,year",2019,i)
+ shifted (4cm,i *cm / 2);
+endfor ;
+
+for i=1 upto 20 :
+ draw
+ thefmttext(decimal i)
+ shifted (1cm,-i/2*cm);
+ draw
+ thefmttext("@!month!",i)
+ shifted (4cm,-i/2*cm);
+ draw
+ thefmttext("@!weekday!",i)
+ shifted (7cm,-i/2*cm);
+ draw
+ thefmttext("@!monthshort!",i)
+ shifted (10cm,-i/2*cm);
+ draw
+ thefmttext("@3!dayoftheweek!",i,1,2018)
+ shifted (13cm,-i/2*cm);
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[title=formatters,reference=fig:formatters]
+ \framed{\scale[width=.8\textwidth]{\processMPbuffer}}
+\stopplacefigure
\stopsection
@@ -3582,6 +3666,213 @@ a default value of 20.
\stopsection
+\startsection[title=Grouping]
+
+The grouping model in \METAPOST\ is kind of special. Basically anything that
+happens in a group is processed in some nested action and doesn't interfere with
+the outside. However, the last value put (back) into the input is picked up after
+the group. A \type {vardef} acts that way:
+
+\startbuffer
+vardef foo (expr i, j) =
+ save ii, jj ; ii := 2*i ; jj :=j/2 ;
+ (i, j) -- (ii,jj)
+enddef ;
+
+draw (foo(1,2) .. foo(5,1) .. foo(12,3))
+ ysized 1cm
+ withpen pencircle scaled 2mm
+ withcolor darkred ;
+
+draw boundingbox currentpicture withcolor darkyellow ;
+\stopbuffer
+
+\typebuffer
+
+This weird shape comes out:
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+We save two variables, and then give new local numerics with their names some
+values. Then we \quote {return} a path. A \type {vardef} automatically starts
+with a \type {begingroup} and ends with an \type {endgroup}. The next example
+shows how we can use that grouping trick directly. The \type {--} has to come
+before the \type {begingroup}.
+
+\startbuffer
+vardef turtle expr p =
+ save a ; pair a ; a := point 0 of p ; a
+ for i = 1 upto length(p) if cycle p : - 1 fi :
+ -- begingroup a := a shifted point i of p ; a endgroup
+ endfor
+ if cycle p : -- cycle fi
+enddef ;
+
+draw ((0, 0) -- (10, 0) -- (100, 10) -- (-5,20) -- cycle)
+ withpen pencircle scaled 2 withcolor darkred ;
+draw turtle ((0, 0) -- (10, 0) -- (100, 10) -- (-5,20) -- cycle)
+ withpen pencircle scaled 2 withcolor darkyellow ;
+\stopbuffer
+
+\typebuffer
+
+Turtle graphics use relative positions. Actually they use one number and switch
+direction but the above is okay too. Effectively we loop over the path and use
+each point as a relative move, so we recalculate it.
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+We could have said \type {-- hide(a := a shifted point i of p) a} because the
+\type {hide} macro does that the grouping trick.
+
+\stopsection
+
+\startsection[title=External files]
+
+You can put code in an external file and load that one when needed. The low level
+command is \type {input}:
+
+\starttyping
+input myfile ;
+input myfile.mp ;
+input myfile.mpiv ;
+input myfile.mpxl ;
+input "myfile.mpxl" ;
+\stoptyping
+
+In \CONTEXT\ we have modules and their name starts with \type {mp-} and the
+suffix can depend on what version you use (\type {mpii}, \type {mpiv}, \type
+{mpxl}) but that will be dealt with automatically.
+
+\starttyping
+loadmodule("mine") ;
+\stoptyping
+
+This will locate \type {mp-mine} with the proper suffix and often a module will
+be set up to be loaded only once. For loading files \LUAMETAFUN\ provides:
+
+\starttyping
+loadfile("somefile.mp") ;
+\stoptyping
+
+Which is a bit more robust than the \type {input} commands that is kind of fuzzy
+because it takes a sequence of tokens or a string. When you embed code in a
+document source there are some environments that permit loading of definitions
+and extensions.
+
+\starttyping
+\startMPdefinitions
+ % code passed to the library directly
+\stopMPdefinitions
+
+\startMPextensions
+ % code passed to the library but via tex (expansion step)
+\stopMPextensions
+\stoptyping
+
+\stopsection
+
+\startsection[title=Instances]
+
+The library supports several numbering models. The default is \type {scaled} that
+uses integers that represent a (relatively small) float. Although you can go up
+to 32K it's wise to stay below 4096. The \type {double} number model supports 64
+bit floating point and the \type {decimal} model arbitrary precision. In \LUATEX\
+there is also \type {binary} for arbitrary precision but in \LUAMETATEX\ that
+model is not provided.
+
+You can use different models and instances alongside. In \MKIV\ and \LMTX\ we have
+a few predefined. The \type {metafun} instance is the default. Here we show the
+ones that use \METAFUN:
+
+\starttyping[style=\ttx]
+\defineMPinstance[metafun] [format=metafun,extensions=yes,initializations=yes]
+\defineMPinstance[minifun] [format=minifun,extensions=yes,initializations=yes]
+\defineMPinstance[extrafun] [format=metafun,extensions=yes,initializations=yes]
+\defineMPinstance[lessfun] [format=metafun]
+\defineMPinstance[doublefun] [format=metafun,extensions=yes,initializations=yes,method=double]
+\defineMPinstance[decimalfun][format=metafun,extensions=yes,initializations=yes,method=decimal]
+\defineMPinstance[mprun] [format=metafun,extensions=yes,initializations=yes]
+\defineMPinstance[simplefun] [format=metafun,method=double] % for internal usage
+\stoptyping
+
+All instances will load additional definitions btu extensions (expanded
+definitions) and initializations (before each graphic) are optional.
+
+\starttyping
+\startMPdefinitions
+\stopMPdefinitions
+
+\startMPextensions
+\stopMPextensions
+
+\startMPinitializations
+\stopMPinitializations
+\stoptyping
+
+You can search the sources of manuals and test suite for examples of usage, but here are
+some:
+
+\startbuffer
+\defineMPinstance[foo][definitions=yes]
+\defineMPinstance[bar][definitions=yes]
+
+\startMPdefinitions{foo}
+ vardef p = image (
+ draw fullsquare scaled 1cm withcolor "darkgreen" ;
+ draw textext("1") ;
+ )
+ enddef ;
+\stopMPdefinitions
+
+\startMPdefinitions{bar}
+ vardef p = image (
+ draw (fullsquare rotated 45) scaled 1cm withcolor "darkyellow" ;
+ draw textext("2") ;
+ )
+ enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We use both as:
+
+\startbuffer[demo-1]
+\startMPcode{foo}
+ draw p ;
+ draw image (
+ draw fullcircle scaled 1cm withcolor "darkblue" ;
+ draw textext("3") withcolor "darkred" ;
+ ) ;
+ draw p ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[demo-2]
+\startMPcode{bar}
+ draw p ;
+ draw image (
+ draw fullcircle scaled 1cm withcolor "darkblue" ;
+ draw textext("4") withcolor "darkred" ;
+ ) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[demo-1,demo-2]
+
+\startlinecorrection
+\startcombination[nx=2,ny=1]
+ {\getbuffer[demo-1]} {foo}
+ {\getbuffer[demo-2]} {bar}
+\stopcombination
+\stoplinecorrection
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-debugging.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
index 4174d34e10b..f8957b5d834 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
@@ -56,9 +56,8 @@ parent point with thin lines.
\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.
+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 ;
@@ -376,6 +375,238 @@ When we overlay these three we get. The envelope only returns the outer curve.
\stopoverlay
\stoplinecorrection
+We show a few nore examples and let it to the user to come up with applications
+for this feature. We start by defining a scaled pen that we apply to a simple
+path that has three point.
+
+\startbuffer
+pen whateverpen ; whateverpen := makepen(fullcircle xyscaled(1/20,1/40));
+
+path p ; p := (origin .. (1,1/2) .. (1,1/4)) scaled 10 ;
+path q ; q := envelope whateverpen of p ;
+
+draw p withpen pencircle xyscaled(1/2,1/4)
+ withcolor "darkgreen" withtransparency (1,.5) ;
+drawpoints p withpen pencircle scaled 1
+ withcolor "darkgray" withtransparency (1,.5) ;
+drawcontrolpoints p withpen pencircle scaled 1/2
+ withcolor "darkmagenta" withtransparency (1,.5) ;
+
+currentpicture := currentpicture shifted (-20,0) ;
+
+draw p withpen pencircle xyscaled(1/2,1/4)
+ withcolor "darkgreen" withtransparency (1,.5) ;
+draw q withpen pencircle scaled 1/5
+ withcolor "darkblue" withtransparency (1,.5) ;
+drawpoints q withpen pencircle scaled 1
+ withcolor "darkgray" withtransparency (1,.5) ;
+drawcontrolpoints q withpen pencircle scaled 1/2
+ withcolor "darkyellow" withtransparency (1,.5) ;
+draw q withpen pencircle scaled 1/50
+ withcolor "white" ;
+
+currentpicture := currentpicture ysized 2cm ;
+\stopbuffer
+
+\typebuffer
+
+On the left we see the path drawn with a circular pen. The points and control
+points are also shown. The path is repeated on the right but there it gets the
+envelope overlayed. We show the points and control points of the envelope: they
+nearly overlap but that depends of course on the used pen.
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+In order to illustrate that the envelope is an outline we blow up a piece of
+this image:
+
+\startlinecorrection[blank]
+ \scale[height=3cm]{\clip[nx=10,ny=20,x=9,y=7]{\processMPbuffer}}
+\stoplinecorrection
+
+Without further explanation we let you ponder the results of the following code.
+
+\startbuffer
+drawoptions(withcolor "darkred") ;
+draw (envelope pensquare of (up--left)) ;
+draw (up--left) shifted (4,0) withpen pensquare ;
+draw fullcircle shifted (8,0) ;
+draw (envelope pensquare of fullcircle) shifted (12,0) ;
+draw (fullcircle) shifted (16,0) withpen pensquare ;
+draw (fullcircle) shifted (20,0) withpen pencircle ;
+currentpicture := currentpicture xsized TextWidth ;
+\stopbuffer
+
+\typebuffer
+
+The efficiency of the output of each draw differs a lot because circles are made
+from eight points and because a transformed pen results in two paths. Normally
+that is not something you have to loose sleep over.
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Performance]
+
+On the average performance of \METAPOST\ is quite okay. The original program uses
+scaled numbers, which are floats packed into an integer. The library also
+supports doubles, decimal and binary number models. In \CONTEXT\ we only support
+scaled, double and decimal. Because the library has to support multiple models
+there is more overhead and therefore it is also slower. There's also more dynamic
+memory allocation going on. In the transition from \MKII\ to \MKIV\ some of the
+critical code (like the code involved in passing \TEX\ states to \METAPOST) had
+to be optimized, although when the \LUA\ interface was added, betters ways became
+possible. We have to accept the penalty in performance and often can gain back a
+lot because we have the \LUA\ interface.
+
+One of the main bottlenecks in storing quantities. \footnote {Recently, Taco
+Hoekwater has done some excellent explanations about the way \METAPOST\ scans the
+input and create variables and you can find his presentations at meetings on the
+\CONTEXT\ garden.} When we see something \type {a[1]} and \type {a[3]} the \type
+{a} is a root variable and the \type {1} and {3} are entries in a linked list
+from that root. It's not an array in the sense that there is some upper bound and
+that there's also a slot \type {2}. There is order but the list is sparse. When
+access is needed, for instance to do some calculations, a linear lookup (from the
+head of the list) takes place. This is quite okay performance wise because
+normally these list are small. The same is true for a path, which is also a
+linked list. If you need point 25, it is looked up by starting at the first knot
+of the path. The longer the path, the more time it takes to reach arbitrary
+points. In the \LUA\ chapter we give an example of how to get around that
+limitation.
+
+Concerning the arrays, here is s trick to get around a performance bottleneck:
+
+\starttyping
+numeric foo[];
+
+def set_foo(expr c, s) =
+ foo[c] := s ;
+enddef ;
+
+def get_foo(expr c) =
+ foo[c]
+enddef ;
+\stoptyping
+
+If you use this as follows:
+
+\starttyping
+numeric n ; n = 123 ;
+
+for i=1 upto 20000 :
+ set_foo(i,n) ;
+endfor ;
+
+for i=1 upto 20000 :
+ n := get_foo(i) ;
+endfor ;
+\stoptyping
+
+the runtime can (for instance) be 3.3 seconds, but when you use the following
+variant, it goes down to 0.13 seconds.
+
+\starttyping
+numeric foo[][][][]; % 12345 : 1 12 123 44 instead of 12344
+
+def set_foo(expr c, s) =
+ foo[c div 10000][c div 1000][c div 100][c] := s ;
+enddef ;
+def get_foo(expr c) =
+ foo[c div 10000][c div 1000][c div 100][c]
+enddef ;
+\stoptyping
+
+This time the lookup is not split into phases each being relatively fast. So, in
+order to reach slot 1234 the engine doesn't have to check and jump over what
+comes before that. You basically create a tree here: 0 (hit), 1000 (hit in one),
+200 (hit in two), 34 (hit in 34). We could go to a single digit but that doesn't
+save much. Before we had ways to store data at the \LUA\ end we used this a few
+times in macros that dealt with data (like Alan Braslau's node and graphics
+modules). This is typically something one can figure out by looking at the (non
+trivial) source code.
+
+Here is another example. In \LUA\ we can easily create a large file, like this:
+
+\starttyping
+\startluacode
+ local t = { }
+ for i=1,10000 do
+ t[i] = string.rep(
+ "here we have number " ..
+ tostring(i) ..
+ " out of the 10000 numbers that we will test"
+ ,100)
+ end
+ t = table.concat(t,"\n")
+ io.savedata("foo1.tmp",t)
+ io.savedata("foo2.tmp",t)
+ io.savedata("foo3.tmp",t)
+\stopluacode
+\stoptyping
+
+We make two copies because we do two experiments and we want to treat them equal with
+respect to caching.
+
+\starttyping
+\startMPcode
+ string f ; f := "foo1.tmp" ;
+ string s[] ;
+ numeric n ; n := 0 ;
+ for i=1 upto 10000 :
+ s[i] := readfrom f ;
+ exitif s[i] = EOF ;
+ n := n + 1 ;
+ endfor ;
+\stopMPcode
+\stoptyping
+
+Say that this runs in 2.2 seconds, how come that the next one runs in 1.7 seconds
+instead?
+
+\starttyping
+\startMPcode
+ string f ; f := "foo2.tmp" ;
+ string s[] ;
+ string ss ;
+ numeric n ; n := 0 ;
+ for i=1 upto 10000 :
+ ss := readfrom f ;
+ exitif ss = EOF ;
+ s[i] := ss ;
+ n := n + 1 ;
+ endfor ;
+\stopMPcode
+\stoptyping
+
+The main reason is that the first case we have two lookups in the linked list
+that determines variable \type {s} and the longer the list, the more time it will
+take. In the second case we use an intermediate variable. Although that means
+extra memory (de)allocation it still pays of. In practice you don't need to worry
+too much about it but of course we can again follow the tree approach:
+
+\startMPcode
+ string f ; f := "foo3.tmp" ;
+ string s[][][] ;
+ string ss ;
+ numeric n ; n := 0 ;
+ for i=1 upto 10000 :
+ ss := readfrom f ;
+ exitif ss = EOF ;
+ s[i div 1000][i div 100][i] := ss ;
+ n := n + 1 ;
+ endfor ;
+\stopMPcode
+
+This time we go down to 1.5 second. Timings could be a bit different in \MKIV\ and
+\LMTX\ because in \LUAMETATEX\ all \METAPOST\ file \IO\ goes through \LUA\ but the
+relative performance gains are the same. With \LUATEX\ and \MKIV\ I measures
+2.9, 2.5 and 2.1 and with \LUAMETATEX\ and \LMTX\ I got 2.3, 1.7 and 1.5.
+
\stopsection
\stopchapter
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-effects.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-effects.tex
index 74e7d487e9e..6c020acda90 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-effects.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-effects.tex
@@ -363,9 +363,9 @@ 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]
+\definecolor[mycolora][darkyellow]
+\definecolor[mycolorb][s=.8]
+\definecolor[mycolorc][darkred]
\stopbuffer
\typebuffer
@@ -386,13 +386,13 @@ First we discuss the old method which is still valid and also available in
\startuniqueMPgraphic{CircularShade}
path p ;
p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
- circular_shade(p,0,\MPcolor{a},\MPcolor{b}) ;
+ circular_shade(p,0,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
\stopuniqueMPgraphic
\startuniqueMPgraphic{LinearShade}
path p ;
p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
- linear_shade(p,0,\MPcolor{a},\MPcolor{b});
+ linear_shade(p,0,\MPcolor{mycolora},\MPcolor{mycolorb});
\stopuniqueMPgraphic
\stopbuffer
@@ -458,7 +458,7 @@ stepping through the color values, we can use the more efficient and generalized
width := \overlaywidth ;
height := \overlayheight ;
path p ; p := unitsquare xscaled width yscaled height ;
- #2_shade(p,#3,\MPcolor{a},\MPcolor{b}) ;
+ #2_shade(p,#3,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
\stopuniqueMPgraphic
\defineoverlay[shade-#1][\uniqueMPgraphic{shade-#1}]%
\framed[background=shade-#1,width=2cm,height=2cm,frame=off]{}}
@@ -501,7 +501,7 @@ stepping through the color values, we can use the more efficient and generalized
% \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}) ;
+% circular_shade(p shifted (i,0),0,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
% endfor ;
% \stopbuffer
%
@@ -518,7 +518,7 @@ stepping through the color values, we can use the more efficient and generalized
% the center of the shading stays at the first circle.
%
% \startbuffer
-% circular_shade(fullcircle scaled 1cm,0,\MPcolor{a},\MPcolor{b}) ;
+% circular_shade(fullcircle scaled 1cm,0,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
% picture s ; s := currentpicture ; currentpicture := nullpicture ;
% for i=0 step 2cm until 8cm :
% addto currentpicture also s shifted (i,0) ;
@@ -544,7 +544,7 @@ stepping through the color values, we can use the more efficient and generalized
\startbuffer
sh := define_circular_shade
- (origin,origin,0,8cm,\MPcolor{a},\MPcolor{b}) ;
+ (origin,origin,0,8cm,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
for i=0 step 2cm until 8cm :
fill fullcircle scaled 1cm shifted (i,0) withshade sh ;
endfor ;
@@ -570,9 +570,9 @@ the shade. The next macro demonstrates the principles in a different way.
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} ;
+ color ca ; ca := \MPcolor{mycolora} ;
+ color cb ; cb := \MPcolor{mycolorb} ;
+ color cc ; cc := \MPcolor{mycolorc} ;
path pa ; pa := fullcircle scaled 2ra shifted a ;
path pb ; pb := fullcircle scaled 2rb shifted b ;
@@ -640,9 +640,9 @@ test_shade(origin shifted (.25cm,0), origin, .50cm, 1cm) ;
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} ;
+ color ca ; ca := \MPcolor{mycolora} ;
+ color cb ; cb := \MPcolor{mycolorb} ;
+ color cc ; cc := \MPcolor{mycolorc} ;
sh := define_linear_shade(a,b,ca,cb) ;
@@ -1472,8 +1472,8 @@ 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 ;
+draw externalfigure "hacker.png" xsized 5cm shifted (-6cm,0) ;
+draw externalfigure "hacker.png" xsized 5cm slanted .5 ;
\stopbuffer
\typebuffer
@@ -1497,7 +1497,7 @@ for i := 1 upto 5 :
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 ;
+ ysized s rotatedaround (c,0 randomized 30) shifted d ;
endfor ;
\stopbuffer
@@ -1516,7 +1516,7 @@ figure inclusion and shading.
\startbuffer
picture p ;
-p := externalfigure "hacker.png" scaled 150pt ;
+p := externalfigure "hacker.png" xsized 150pt ;
clip p to unitcircle scaled 150pt ;
circular_shade(boundingbox p enlarged 10pt, 0, .2red, .9red) ;
addto currentpicture also p ;
@@ -2222,10 +2222,10 @@ The \type {simple} option disables all. The simple results are shown in
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).
+[fig:outlines:features] we see a few examples, one with Pagella (the Zapf quote)
+and one with Dejavu (the Tufte quote).
-\startplacefigure[reference=fig:outlines:features,title={Pagela (\OPENTYPE) and Optima Nova (\TYPEONE)}]
+\startplacefigure[reference=fig:outlines:features,title={Pagela and Dejavu}]
\startcombination[1*4]
\bgroup
\def|#1|{-}%
@@ -2249,24 +2249,24 @@ Pagella (the Zapf quote) and one with Optima Nova (the Tufte quote).
\egroup {pagella / default features}
\bgroup
\def|#1|{-}%
- \definedfont[lt55476.afm*none]% optima nova
+ \definedfont[dejavuserif.ttf*none]%
\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}
+ \egroup {dejavu serif / no features}
\bgroup
\def|#1|{-}%
- \definedfont[lt55476.afm*default]% optima nova
+ \definedfont[dejavuserif.ttf*default]%
\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}
+ \egroup {dejavu serif / default features}
\stopcombination
\stopplacefigure
@@ -2287,6 +2287,219 @@ like:
\processMPbuffer
\stoplinecorrection
+The next example needs the \type {hanbatang-lvt.ttf} font so when you process this
+you might want to install that first. In \MKIV\ and \LMTX\ you can put that font
+in \typ {<texroot>/texmf-fonts/data/hanbantang} or a similar path.
+
+We start by defining the font:
+
+% \definefontfeature
+% [korean-base]
+% [goodies=hanbatanglvt,
+% colorscheme=default,
+% mode=node,
+% script=hang,
+% language=kor]
+
+\startbuffer
+\definefontfeature
+ [korean-base]
+ [goodies=hanbatanglvt,
+ colorscheme=default,
+ mode=node,
+ script=hang,
+ language=kor]
+
+\definefont[KoreanFont][hanbatanglvt*korean-base]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Next we define a macro that will draw the outline:
+
+\startbuffer
+\startMPdefinitions
+ string KoreanColors[] ;
+
+ KoreanColors[1] := "darkred" ;
+ KoreanColors[2] := "darkgreen" ;
+ KoreanColors[3] := "darkblue" ;
+ KoreanColors[4] := "darkyellow" ;
+ KoreanColors[5] := "darkgray" ;
+
+ newinternal KoreanSplit ; KoreanSplit := -1 ;
+ newinternal KoreanCode ; KoreanCode := -2 ;
+ newinternal KoreanMode ; KoreanMode := KoreanSplit ;
+
+ def KoreanOutline(expr txt) =
+ picture p ; p := outlinetext.p(txt) ;
+ numeric n ; n := 0 ;
+ string old, new ; old := "" ;
+ for i within p :
+ if KoreanMode == KoreanSplit :
+ n := n + 1 ;
+ elseif KoreanMode == KoreanCode :
+ new := prescriptpart i ;
+ if new <> old :
+ old := new ;
+ n := n + 1 ;
+ fi ;
+ else :
+ n := KoreanMode ;
+ fi ;
+ if unknown KoreanColors[n] :
+ n := 1 ;
+ fi ;
+ draw pathpart i
+ withpen pencircle scaled 1/10
+ withcolor KoreanColors[n] ;
+ endfor ;
+ enddef ;
+
+ def KoreanTest(expr txt) =
+ image (
+ KoreanMode := KoreanSplit ; KoreanOutline(txt) ;
+ currentpicture := currentpicture shifted (- xpart urcorner currentpicture, 0);
+ KoreanMode := KoreanCode ; KoreanOutline(txt) ;
+ currentpicture := currentpicture shifted (- xpart urcorner currentpicture, 0);
+ KoreanMode := 3 ; KoreanOutline(txt) ;
+ )
+ enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+Because we want to reuse this definition, we define it for all what comes:
+
+\typebuffer \getbuffer
+
+% entered as three characters: ᄅ ᅡ ᆺ (mail collapses)
+%
+% \startMPcode KoreanTest("\KoreanFont 랏") ; \stopMPcode
+
+\startbuffer
+\startcombination[3*2]
+ {\startMPcode draw KoreanTest("\KoreanFont 랏") ysized 15mm ; \stopMPcode} {}
+ {\startMPcode draw KoreanTest("\KoreanFont 논") ysized 15mm ; \stopMPcode} {}
+ {\startMPcode draw KoreanTest("\KoreanFont 왕") ysized 15mm ; \stopMPcode} {}
+ {\startMPcode draw KoreanTest("\KoreanFont 닭") ysized 15mm ; \stopMPcode} {}
+ {\startMPcode draw KoreanTest("\KoreanFont 박") ysized 15mm ; \stopMPcode} {}
+ {\startMPcode draw KoreanTest("\KoreanFont 서") ysized 15mm ; \stopMPcode} {}
+\stopcombination
+\stopbuffer
+
+We use this macro in the following example. The results can be seen in \in
+{figure} [koreanoutlines]. There is one drawback of this example: It contributes
+a lot to the runtime: about 2.5~seconds to a 16~second run without this example.
+\footnote {This is partly due to an enforced intermediate garbage collection
+step.} The font itself loads fast but the outlines take their time because a few
+hundred megabytes of \LUA\ tables are involved. Instead you can define the
+feature to use \typ {goodies=hanbatanglvt} and \typ {colorscheme=default} and
+play with that.
+
+\typebuffer
+
+\startplacefigure[title=Some Korean magic,reference=koreanoutlines]
+ \doifelsemode{optional} {
+ \getbuffer
+ } {
+ \framed{A large optional example is not shown here!}
+ }
+\stopplacefigure
+
+On the mailing list occasionally questions pop op with respect to outlines and
+user Garulfo came up with a neat solution for shaded text. First some examples:
+
+\startbuffer
+\startMPcode
+ picture p ; p := lmt_outline [
+ text = "\strut foo f o o",
+ drawcolor = "white",
+ rulethickness = .2
+ ] ysized 3cm ;
+ fill boundingbox p
+ withshademethod "linear"
+ withshadedirection(0,1)
+ withshadecolors ("darkblue", "darkyellow") ;
+ draw p;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+Here the background shines through the text:
+
+\startlinecorrection \getbuffer \stoplinecorrection
+
+You can actually use the effects features which for a larger text is more
+efficient because it just renders the font differently. The result is
+shown in \in {figure} [fig:effects:text].
+
+\startbuffer[effects-text]
+\startuseMPgraphic{MyShade}
+ fill OverlayBox
+ withshademethod "linear"
+ withshadedirection(0,1)
+ withshadecolors (red, blue) ;
+\stopuseMPgraphic
+
+\defineoverlay[MyShade][\useMPgraphic{MyShade}]
+
+\setupbackgrounds[page][background=MyShade]
+
+\startmakeup
+ \definedfont[SerifBold*default @ 50pt] \setupinterlinespace
+
+ \defineeffect[MyOutline][alternative=outer,rulethickness=1pt]
+
+ \startcolor[white]
+ \starteffect[MyOutline]
+ \input jojomayer
+ \stopeffect
+ \stopcolor
+\stopmakeup
+\stopbuffer
+
+\typebuffer[effects-text]
+
+\startplacefigure[title=Regular text effects,reference=fig:effects:text]
+ \typesetbuffer[effects-text][height=.3\textheight]
+\stopplacefigure
+
+We now come to the neat example:
+
+\startbuffer
+\startMPcode
+ picture tt ; tt := lmt_outline [
+ kind = "fillup",
+ text = "\definedfont[name:texgyrepagellabold*default]foo f o o",
+ ] xsized 12cm ;
+
+ path bb ; bb := boundingbox tt ;
+
+ path pp ; pp := bb enlarged 2cm ;
+
+ fill pp
+ withshademethod "linear"
+ withshadedirection down
+ withshadecolors ("darkred", "darkblue") ;
+
+ for i within tt :
+ nofill pathpart i;
+ endfor ;
+
+ eofill bb withcolor "darkgray" ;
+ clip currentpicture to bb ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+It uses a clever combination of refilling the shape and background:
+
+\startlinecorrection
+ \getbuffer
+\stoplinecorrection
+
\stopsection
\startsection[title=Transparency groups]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex
index 409839cbafe..8a30aad7c68 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex
@@ -71,9 +71,11 @@
\setuppagenumbering
[alternative=doublesided]
+\definefontfallback[moremono] [dejavusansmono] [0x0000-0xFFFF] [rscale=0.85]
+
\definetypeface [metafunbodyfont] [rm] [serif] [pagella] [default]
\definetypeface [metafunbodyfont] [ss] [sans] [modern] [default]
-\definetypeface [metafunbodyfont] [tt] [mono] [modern] [default]
+\definetypeface [metafunbodyfont] [tt] [mono] [modern] [default] [fallbacks=moremono]
\definetypeface [metafunbodyfont] [mm] [math] [palatino] [default]
\setupbodyfont [metafunbodyfont,10pt] % 11 pt and 12pt -> errors due to intersection mess
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment.tex
index ca9fc24b3fa..57875008dbe 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-environment.tex
@@ -182,24 +182,50 @@
\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 ChapterCommand #1#2
\ifconditional\headshownumber
- \ifdim\leftmarginwidth<\rightmarginwidth
- \donetrue
- \else
- \donefalse
- \fi
- \hskip-\ifdone\leftmargintotal\else\rightmargintotal\fi
+ \hskip-\leftmargintotal\relax
\framed [
background=titled,
frame=off,
offset=0pt
] {
- \hbox to \ifdone\leftmarginwidth\else\rightmarginwidth\fi {
+ \hbox to \leftmarginwidth {
#1
\hss
}
- \hskip\ifdone\leftmargindistance\else\rightmargindistance\fi
+ \hskip\leftmargindistance\relax
#2
}
\else
@@ -316,7 +342,7 @@
\startbuffer[shape-a]
\startuniqueMPgraphic{meta:hash}{linewidth,linecolor,angle,gap}
- if unknown context_back : input mp-back ; fi ;
+ loadmodule("back") ;
some_hash ( OverlayWidth, OverlayHeight ,
\MPvar{linewidth}, \MPvar{linecolor} ,
\MPvar{angle}, \MPvar{gap} ) ;
@@ -343,7 +369,7 @@
\startbuffer[symb-a]
\startuniqueMPgraphic{meta:button}{type,size,linecolor,fillcolor}
- if unknown context_butt : input mp-butt ; fi ;
+ loadmodule("butt") ;
some_button ( \MPvar{type},
\MPvar{size},
\MPvar{linecolor},
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-examples.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-examples.tex
index 4e5e0eed310..5549a3bdd85 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-examples.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-examples.tex
@@ -3264,6 +3264,259 @@ We get:
\stopsection
+\startsection[title=Educational]
+
+I made this example long ago, when some family member had to learn tables by
+heart. For some reason, at school, this is made into a complex issue, with tricks
+and such, even it if only involves only a few numbers. My own experience (if I
+remember right) was that some of these numbers are trivial, and that there is
+quite some symmetry, so in practice only a quarter needs to be remembered. And,
+assuming that you can easily deduct the trivial cases, one can just calculate the
+rest if needed.
+
+\startbuffer
+\start \ttbf \startMPcode
+ def MyDraw(expr i, j, c) =
+ fill fullsquare shifted (i,j) withcolor c withtransparency (1,.5) ;
+ enddef ;
+
+ for i = 1 upto 10 :
+ for j = 1 upto 10 : MyDraw( i, -j, "middlered" ) ; endfor ; endfor ;
+
+ for j = 1 upto 10 : MyDraw( 1, -j, "middleblue" ) ; endfor ;
+ for i = 1 upto 10 : MyDraw( i, -10, "middlegreen" ) ; endfor ;
+ for i = 1 upto 10 : MyDraw( i, -1, "middleyellow") ; endfor ;
+ for j = 1 upto 10 : MyDraw(10, -j, "middlecyan" ) ; endfor ;
+ for j = 1 upto 10 : MyDraw( 5, -j, "middlegray" ) ; endfor ;
+ for j = 1 upto 10 : MyDraw( j, -j, "middlegray" ) ; endfor ;
+
+ draw image ( for i = 1 upto 10 : for j = 1 upto 10 :
+ draw textext(decimal (i*j)) ysized .25 shifted (i,-j) ;
+ endfor ; endfor ; ) withcolor white ;
+
+ currentpicture := currentpicture ysized 10cm ;
+\stopMPcode \stop
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[title=Overlapping glyphs,reference=fig:tentable]
+ \getbuffer
+\stopplacefigure
+
+Here we use both transparency and colors to stress the reduction of cases. The
+named colors resolve to ones defined at the \TEX\ end. We see the redndering
+\in {figure} [fig:tentable].
+
+\startsection[title=Glyph magic]
+
+The next example is the result of a tread on the mailing list. After Henri Menke
+posted a some glyph overlap code, I made a variant that more suited the way we do
+it in \METAFUN. In the meantime Floris van Maanen had found out that some glyphs
+need a more inventive solution so after that the code evolved. By then the \type
+{outlinetext}, \type {drawoutlinetext} and \type {filloutlinetext} helpers had
+been added to the code base.
+
+Because this is complicated stuff, we just show the two solutions. The first one
+is a relative simple one, the second one uses an approach suggested by Alan
+Braslau and therefore uses some of the code that can be found in the \type
+{crossingunder} macro.
+
+\startbuffer
+\startMPdefinitions
+def ShowOverlapInOutlinesA(expr first, second) =
+ path p_i, p_j, s_i, s_j ;
+ numeric n_i, n_j, index ;
+ pair found ;
+ index := 0 ;
+ for i within first :
+ for j within second :
+ p_i := pathpart i ; n_i := length(p_i) ;
+ p_j := pathpart j ; n_j := length(p_j) ;
+ for ii = 0 upto n_i - 1 :
+ s_i := subpath(ii,ii+1) of p_i ;
+ for jj = 0 upto n_j - 1 :
+ s_j := subpath(jj,jj+1) of p_j ;
+ found := s_i intersection_point s_j ;
+ if intersection_found :
+ index := index + 1 ;
+ drawdot found
+ withpen pencircle scaled 4 withcolor white ;
+ draw textext("\strut\ttbf " & decimal index) ysized 3
+ shifted found ;
+ fi ;
+ endfor ;
+ endfor ;
+ endfor ;
+ endfor ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This is the solution based on \type {crossingunder}, a macro that has been
+introduced as part of Alan's neat node module.
+
+\startbuffer
+\startMPdefinitions
+def ShowOverlapInOutlinesB(expr first, second) =
+ begingroup ;
+ save p, q, n, t, a, b, c, bcuttings, hold, found ;
+ path p, q ;
+ numeric n, hold ;
+ path a, b, c, bcuttings ;
+ pair found ;
+ c := makepath(currentpen scaled crossingscale) ;
+ for f within first :
+ numeric t[];
+ path hold[];
+ t[0] := n := hold := 0 ;
+ for s within second :
+ p := pathpart f ;
+ q := pathpart s ;
+ a := p ;
+ for i=1 upto crossingnumbermax : % safeguard
+ clearxy ; z = a intersectiontimes q ;
+ if x < 0 :
+ exitif hold < 1 ;
+ a := hold[hold] ; hold := hold - 1 ;
+ clearxy ; z = a intersectiontimes q ;
+ fi
+ (t[incr n], whatever) = p intersectiontimes point x of a ;
+ if x = 0 :
+ a := a cutbefore c shifted point x of a ;
+ elseif x = length a :
+ a := a cutafter c shifted point x of a ;
+ else : % before or after?
+ b := subpath (0,x) of a cutafter c shifted point x of a ;
+ bcuttings := cuttings ;
+ a := subpath (x,length a) of a cutbefore c shifted point x of a ;
+ clearxy ; z = a intersectiontimes q ;
+ if x < 0 :
+ a := b ;
+ cuttings := bcuttings ;
+ elseif length bcuttings > 0 :
+ clearxy ; z = b intersectiontimes q ;
+ if x >= 0 :
+ hold[incr hold] := b ;
+ fi
+ fi
+ fi
+ if length cuttings = 0 :
+ exitif hold < 1 ;
+ a := hold[hold] ; hold := hold - 1 ;
+ fi
+ endfor ;
+ endfor ;
+ t[incr n] = length p ;
+ for i=1 upto n :
+ found := point t[i] of p ;
+ drawdot found
+ withpen pencircle scaled 4 withcolor white ;
+ draw textext("\strut\ttbf " & decimal i) ysized 3
+ shifted found ;
+ endfor ;
+ endfor ;
+ endgroup ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We demonstrate the differences with an example. The result can be seen in
+\in {figure} [fig:overlapping:a].
+
+\startbuffer
+\startcombination
+ {\startMPcode
+ picture first, second ;
+ first := outlinetext.p("N") ; first := first scaled 10 ;
+ second := outlinetext.p("T") ; second := second scaled 10 ;
+ second := second rotatedaround(center second, 5) shifted (1,-1) ;
+ filloutlinetext(first ) withcolor .5[darkblue,white] ;
+ filloutlinetext(second) withcolor .5[darkred,white] ;
+ drawoutlinetext(first ) ;
+ drawoutlinetext(second) ;
+ ShowOverlapInOutlinesA(first, second) ;
+ addbackground withcolor darkgray ;
+ currentpicture := currentpicture scaled 2.5 ;
+ \stopMPcode} {Method A}
+ {\startMPcode
+ picture first, second ;
+ first := outlinetext.p("N") ; first := first scaled 10 ;
+ second := outlinetext.p("T") ; second := second scaled 10 ;
+ second := second rotatedaround(center second, 5) shifted (1,-1) ;
+ filloutlinetext(first ) withcolor .5[darkgreen,white] ;
+ filloutlinetext(second) withcolor .5[darkyellow,white] ;
+ drawoutlinetext(first ) ;
+ drawoutlinetext(second) ;
+ ShowOverlapInOutlinesB(first, second) ;
+ addbackground withcolor darkgray ;
+ currentpicture := currentpicture scaled 2.5 ;
+ \stopMPcode} {Method B}
+\stopcombination
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[title=Overlapping glyphs,reference=fig:overlapping:a]
+ \getbuffer
+\stopplacefigure
+
+We duplicate some code because the pictures will change in the process of
+analyzing. Let's make a helper for that:
+
+\startbuffer
+\startMPdefinitions
+def ShowOverlap(expr f, s, m) =
+ picture first, second ;
+ first := outlinetext.p(f) ; first := first scaled 10 ;
+ second := outlinetext.p(s) ; second := second scaled 10 ;
+
+ filloutlinetext(first ) withcolor darkblue ;
+ drawoutlinetext(first ) ;
+
+ filloutlinetext(second) withcolor darkred ;
+ drawoutlinetext(second) ;
+
+ if m == 2 :
+ ShowOverlapInOutlinesB
+ else :
+ ShowOverlapInOutlinesA
+ fi (first, second) ;
+
+ addbackground withcolor darkgray ;
+ currentpicture := currentpicture ysized 4cm ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Again we demonstrate the differences with some examples. The result can be seen in
+\in {figure} [fig:overlapping:b].
+
+\startbuffer
+ \startcombination[nx=3,ny=2]
+ {\startMPcode ShowOverlap("N","T",1) ; \stopMPcode} {Method 1}
+ {\startMPcode ShowOverlap("\$","Q",1) ; \stopMPcode} {Method 1}
+ {\startMPcode ShowOverlap("\tttf ABC","\tttf PQR",1) ; \stopMPcode} {Method 1}
+ {\startMPcode ShowOverlap("N","T",2) ; \stopMPcode} {Method 2}
+ {\startMPcode ShowOverlap("\$","Q",2) ; \stopMPcode} {Method 2}
+ {\startMPcode ShowOverlap("\tttf ABC","\tttf PQR",2) ; \stopMPcode} {Method 2}
+ \stopcombination
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[title=Overlapping glyphs,reference=fig:overlapping:b]
+ \getbuffer
+\stopplacefigure
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex
index 9010fc403e6..014bd66e81c 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex
@@ -361,6 +361,8 @@ second argument in the next line:
\starttyping
\startuniqueMPgraphic{smile}{type,height,color}
+ % the image
+\stopuniqueMPgraphic
\stoptyping
Because unique graphics often are used in backgrounds, its uniqueness is
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-introduction.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-introduction.tex
index b519055c041..e2c33f6f3e8 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-introduction.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-introduction.tex
@@ -88,6 +88,15 @@ 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.
+The first version of \METAFUN\ evolved in \CONTEXT\ \MKII, and when we moved to
+\MKIV\ some interfaces (especially the extensions) could be made better. We now
+have \LMTX\ so we can make even those better (and often easier). The downside is
+that some features discussed here won't work in \MKII\ and \MKIV. If you run into
+that, just consider updating to \LMTX. The current version should process okay
+with the latest version; thanks to Otared Kavian for keeping an eye on that and
+posting me possible issues. The real new features are part of what is to become
+\LUAMETAFUN, but for that we have a separate manual.
+
\blank[big,samepage]
\startlines
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-layout.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-layout.tex
index 2be7e19ff3f..e81800bb43a 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-layout.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-layout.tex
@@ -327,9 +327,11 @@ 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
+\pushoverloadmode
\startquotation
\def\processwords#1{#1}\getbuffer[lions]
\stopquotation
+\popoverloadmode
The low level \CONTEXT\ macro \type {\processwords} provides a mechanism to treat
the individual words of its argument. The macro is called as follows:
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-lua.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-lua.tex
index 0794fc87919..e445cef53f9 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-lua.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-lua.tex
@@ -24,11 +24,17 @@ of a graphic from data but often it makes more sense to do the reverse. I finall
found time and reason to look into this and in the following sections I will
describe how it's done.
-\stopintro
+\blank
-\startsection[title=Introduction]
+{\bi The \LUA\ interface in \MKIV\ is way more limited than in \LMTX\ and new
+features will only show up in \LMTX, simply because the \METAPOST\ library in
+\LUAMETATEX\ is more powerful.}
-\stopsection
+\stopintro
+
+% \startsection[title=Introduction]
+%
+% \stopsection
\startsection[title=The basics]
@@ -232,7 +238,7 @@ helper is \type {mp.quoted}, as in:
\startbuffer
draw
- textext(lua("mp.quoted('@0.3f'," & decimal n & ")"))
+ textext(lua("mp.quoted('@0.3f'," & decimal 1.234 & ")"))
withcolor darkred ;
\stopbuffer
@@ -416,73 +422,73 @@ So in the end we can simplify the code that we started with to:
\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=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]
@@ -678,53 +684,53 @@ 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
+% 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:
@@ -1167,285 +1173,600 @@ the same name defined.
\stopsection
-\startsection[title=Large paths]
+\startsection[title=Accessing paths]
-The plugins (like those dealing with text) also use calls in the \type {mp}
-namespace but they have sort of protected names, starting with \type {mf_}. These
-are visible but not meant to be used by users. Not only can their name change,
-their functionality can as well.
+A path in \METAPOST\ is internally a linked list of knots and each knot has a
+coordinate and two control points. Access to specific points of very large path
+can be somewhat slow. First of all, the lookup start at the beginning and when
+you use fractions (say halfway between point 4 and 5) the engine has to find the
+spot. For this (and other reasons not mentioned here) we have a way to access
+paths different, using \LUA\ behind the scenes.
-The following are actually private as they have related macros but also have a
-public alias:
+\startbuffer
+path p ; p := fullcircle xysized (4cm,2cm) ;
+for i inpath p:
+ drawdot leftof i withpen pencircle scaled 2mm withcolor darkred ;
+ drawdot pointof i withpen pencircle scaled 3mm withcolor darkgreen ;
+ drawdot rightof i withpen pencircle scaled 2mm withcolor darkblue ;
+endfor ;
+draw for i inpath p:
+ pointof i .. controls (leftof i) and (rightof i) ..
+endfor cycle withpen pencircle scaled .5mm withcolor white ;
+
+p := p shifted (5cm,0) ;
+draw for i inpath p:
+ pointof i --
+endfor cycle withpen pencircle scaled .5mm withcolor .5white ;
+for i inpath p:
+ drawdot pointof i withpen pencircle scaled 3mm withcolor darkgreen ;
+endfor ;
+\stopbuffer
-\startlines
-lua.mp.pathlength(name)
-lua.mp.pathpoint(i)
-lua.mp.pathleft(i)
-lua.mp.pathright(i)
-lua.mp.pathreset()
-\stoplines
+\typebuffer
-They are meant for special high|-|performance path access, for example:
+Here we access the main coordinate and the two control points. The last draw is of course
+just mimicking drawing the path.
-\startlinecorrection
-\startMPcode
- save p, q, r;
- path p ; p := for i=1 upto 1000 :
- (i,0) -- (i,4 + uniformdeviate 4) --
- endfor cycle ;
- fill p xysized (TextWidth,20mm) withcolor red ;
-
- path q ; q := for i=1 upto lua.mp.pathlength("p") :
- if (i mod 4) == 0 : lua.mp.pathpoint(i) -- fi
- endfor cycle ;
- fill q xysized (TextWidth,2cm) shifted (0,-45mm) withcolor green ;
-
- path r ; r := for i inpath p :
- if not odd (i) : pointof i -- fi
- endfor cycle ;
- fill r xysized (TextWidth,2cm) shifted (0,-70mm) withcolor blue ;
-\stopMPcode
+\startlinecorrection[blank]
+\processMPbuffer
\stoplinecorrection
-Because a lookup of a point in \METAPOST\ is a linear lookup over a linked list
-for very large paths the gain is significant when using \LUA\ because there the
-points are stored in an indexed table. The left and right points can be used
-vebose like
+\stopsection
-\starttyping
-lua.mp.pathpoint(i) controls lua.mp.pathleft(i) and lua.mp.pathright(i)
-\stoptyping
+\startsection[title=Acessing \TEX]
-or more terse:
+In \MKIV\ and \LMTX\ it is possible to access \TEX\ registers and macros from the
+\METAPOST\ end. Let's first define and set some:
-\starttyping
-pointof i controls leftof i and rightof i
-\stoptyping
+\startbuffer
+\newdimen\MyMetaDimen \MyMetaDimen = 2mm
+\newcount\MyMetaCount \MyMetaCount = 10
+\newtoks \MyMetaToks \MyMetaToks = {\bfd \TeX}
+ \def\MyMetaMacro {not done}
+\stopbuffer
-Beware: this kind of trickery is {\em only} needed when you have very large paths
-that are to be manipulated and the. Otherwise it's overkill.
+\typebuffer \getbuffer
-\stopsection
+\startbuffer
+\startMPcode
+ for i=1 upto getcount("MyMetaCount") :
+ draw fullcircle scaled (i * getdimen("MyMetaDimen")) ;
+ endfor ;
+ draw textext(gettoks("MyMetaToks")) xsized 15mm withcolor darkred ;
+ setglobaldimen("MyMetaDimen", bbwidth(currentpicture)) ;
+ setglobalmacro("MyMetaMacro", "done") ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
-\startsection[title={Interfacing to \TEX}]
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
-The next bunch of calls is for accessing \TEX\ registers. You can set their
-values and get them as well.
+We can now look at the two updated globals where \type {\MyMetaMacro: \the\MyMetaDimen}
+typesets: {\tttf \MyMetaMacro: \the\MyMetaDimen}. As demonstrated you can best define your
+own registers but in principle you can also access system ones, like \type {\scratchdimen}
+and friends.
-\starttyping
-lua.mp.getmacro(k)
-lua.mp.getdimen(k)
-lua.mp.getcount(k)
-lua.mp.gettoks (k)
-
-lua.mp.setmacro(k,v)
-lua.mp.setdimen(k,v)
-lua.mp.setcount(k,v)
-lua.mp.settoks (k,v)
-\stoptyping
+\stopsection
+
+\startsection[title=Abstraction]
-When you mess around with variables and run into issues it might help to
-report values on the console. The \type {report} function does this:
+We will now stepwise implement some simple helpers for accessing data in files.
+The examples are kind of useless but demonstrate how interfaces evolved. The
+basic command to communicate with \LUA\ is \type {runscript}. In this example
+we will load a (huge) file and run over the lines.
\starttyping
-lua.mp.report(a,b)
+\startMPcode{doublefun}
+ save q ; string q ; q := "'\\" & ditto & "'" ;
+ runscript (
+ "GlobalData = string.splitlines(io.loaddata('foo.tmp')) return ''"
+ ) ;
+ numeric l ; l = runscript (
+ "return string.format('\letterpercent q',\letterhash GlobalData)"
+ );
+ for i=1 step 1 until l :
+ l := length ( runscript (
+ "return string.format('\letterpercent q',GlobalData[" & decimal i & "])"
+ ) ) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
\stoptyping
-\startlinecorrection
-\startMPcode
-lua.mp.report("status","a circle") ;
-fill fullcircle xyscaled (2cm,1cm) withcolor red ;
-lua.mp.report("status","its boundingbox [@N,@N,@N,@N]",
- xpart llcorner currentpicture, ypart llcorner currentpicture,
- xpart urcorner currentpicture, ypart urcorner currentpicture
-) ;
-draw boundingbox currentpicture withcolor blue ;
-report("status","the size: @Nbp x @Nbp",
- bbwidth(currentpicture), bbheight(currentpicture)
-) ;
-message("done") ;
-\stopMPcode
-\stoplinecorrection
+The \type {runscript} primitive takes a string and should return a string (in
+\LUAMETATEX\ you can also return nothing). This low level solution will serve as
+our benchmark: it takes 2.04 seconds on the rather large (64MB) test file with
+10.000 lines.
-The console shows:
+The code looks somewhat clumsy. This is because in \METAPOST\ escaping is not
+built in so one has to append a double quote character using \type {char 34} and
+the \type {ditto} string is defined as such. This mess is why in \CONTEXT\ we
+have an interface:
\starttyping
-metapost > status : a circle
-metapost > status : its boundingbox [-28.34645,-14.17323,28.34645,14.17323]
-metapost > status : the size: 57.1929bp x 28.84647bp
-metapost > message : done
+\startMPcode{doublefun}
+ lua("GlobalData = string.splitlines(io.loaddata('foo.tmp'))") ;
+ numeric l ;
+ for i=1 step 1 until lua("mp.print(\#GlobalData)") :
+ l := length(lua("mp.quoted(GlobalData[" & decimal i & "])")) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
\stoptyping
-There are two more getters. These can be used to access the specific graphic
-related variables set at the \TEX\ end.
+As expected we pay a price for the additional overhead, so this time we need 2.28
+seconds to process the file. The return value of a run is a string that is fed
+into \type {scantokens}. Here \type {print} function prints the number as string
+and that gets scanned back to a number. The \type {quoted} function returns a
+string in a string so when we're back in \METAPOST\ that gets scanned as string.
+
+When code is used more frequently, we can make a small library, like this:
\starttyping
-mp.texvar(name)
-mp.texstr(name)
+\startluacode
+ local MyData = { }
+ function mp.LoadMyData(filename)
+ MyData = string.splitlines(io.loaddata(filename))
+ end
+ local mpprint = mp.print
+ local mpquoted = mp.quoted
+ function mp.MyDataSize()
+ mpprint(#MyData)
+ end
+ function mp.MyDataString(i)
+ mpquoted(MyData[i] or "")
+ end
+\stopluacode
\stoptyping
-If you have adaptive styles you might want to test for modes.
+It is not that hard to imagine a more advanced mechanisms where data from multiple
+files can be handled at the same time. This code is used as:
\starttyping
-if lua.mp.mode("screen") : % or processingmode
- % some action only needed for screen documents
-fi ;
-if lua.mp.systemmode("first") :
- % some action for the first run
-fi ;
+\startMPcode{doublefun}
+ lua.mp.LoadMyData("foo.tmp") ;
+ numeric l ;
+ for i=1 step 1 until lua.mp.MyDataSize() :
+ l := length(lua.mp.MyDataString(i)) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
\stoptyping
-For convenience these are wrapped into macros:
+The \type {mp} namespace at the \LUA\ end is a subnamespace at the \METAPOST\
+end. This solution needs 2.20 seconds so we're still slower than the first one,
+but in \LUAMETATEX\ with \LMTX we can do better. First the \LUA\ code:
\starttyping
-if texmode("screen") :
- % some action only needed for screen documents
-fi ;
-if systemmode("first") :
- % some action for the first run
-fi ;
+\startluacode
+ local injectnumeric = mp.inject.numeric
+ local injectstring = mp.inject.string
+ local MyData = { }
+ function mp.LoadMyData(filename)
+ MyData = string.splitlines(io.loaddata(filename))
+ end
+ function mp.MyDataSize()
+ injectnumeric(#MyData)
+ end
+ function mp.MyDataString(i)
+ injectstring(MyData[i] or "")
+ end
+\stopluacode
\stoptyping
-When you implement your own helpers you can fall back on some auxiliary functions
-in the \type {mp} namespace. Actually these are collected in \type {mp.aux} and
-thereby protected from being overwritten by mistake. Here they are:
-
-% mp.flush()
-% mp.size(t)
-
-\stopsection
-
-\startsection[title={Interfacing to \METAPOST}]
-
-There is also experimental access to some of the \METAPOST\ internals. In order
-to deal with (large) paths a few more iterator related helpers are provided too.
-
-% mp.set (numeric string path boolean)
+This time we use injectors. The mentioned \type {print} helpers serialize data so
+numbers, pairs, colors etc are converted to a string that represents them that is
+fed back to \METAPOST\ after the snippet is run. Multiple prints are collected
+into one string. An injecter follows a more direct route: it pushes back a proper
+\METAPOST\ data type.
\starttyping
-n = mp.getnumeric(name)
-s = mp.getstring(name)
-b = mp.getboolean(name)
-p = mp.getpath(name)
+\startMPcode{doublefun}
+ lua.mp.LoadMyData("foo.tmp") ;
+ numeric l ;
+ for i=1 step 1 until lua.mp.MyDataSize() :
+ l := length(lua.mp.MyDataString(i)) ;
+ endfor ;
+ draw textext(decimal l);
+\stopMPcode
\stoptyping
-A is path a table of tables that have six values: the coordinates and the
-pre- and postcontrol. You can manipulate this table and feed it back into
-\METAPOST.
+This usage brings us down to 1.14 seconds, so we're still not good. The next
+variant is performing similar: 1.05 seconds.
-\startlinecorrection
-\startMPcode
-numeric n ; n := lua.mp.newhash() ;
-
-for i=1 upto 3 :
- lua.mp.tohash(n,i) ;
-endfor ;
-
-fill fullcircle scaled 10mm withcolor
- if lua.mp.inhash(n,3) : green else : red fi ;
-
-fill fullcircle scaled 5mm withcolor
- if lua.mp.inhash(n,4) : green else : red fi ;
-
-lua.mp.disposehash(n)
+\starttyping
+\startMPcode{doublefun}
+ runscript("mp.LoadMyData('foo.tmp')") ;
+ numeric l ;
+ for i=1 step 1 until runscript("mp.MyDataSize()") :
+ l := length(runscript("mp.MyDataString(" & decimal i & ")")) ;
+ endfor ;
+ draw textext(decimal l);
\stopMPcode
-\stoplinecorrection
+\stoptyping
-You can also store values with keys and access them later:
+We will now delegate scanning to the \LUA\ end.
-\startlinecorrection
-\startMPcode
-numeric n ; n := lua.mp.newhash() ;
-
-for i=1 upto 3 :
- lua.mp.tohash(n,i,decimal sqrt(i)) ;
-endfor ;
+\starttyping
+\startluacode
+ local injectnumeric = mp.inject.numeric
+ local injectstring = mp.inject.string
+ local scannumeric = mp.scan.numeric
+ local scanstring = mp.scan.string
+ local MyData = { }
+ function mp.LoadMyData()
+ MyData = string.splitlines(io.loaddata(scanstring()))
+ end
+ function mp.MyDataSize()
+ injectnumeric(#MyData)
+ end
+ function mp.MyDataString()
+ injectstring(MyData[scannumeric()] or "")
+ end
+\stopluacode
+\stoptyping
-draw textext(lua.mp.fromhash(n,3))
- ysized 1cm
- withcolor blue ;
+This time we are faster than the clumsy code we started with: 0.87 seconds.
-lua.mp.disposehash(n)
+\starttyping
+\startMPcode{doublefun}
+ runscript("mp.LoadMyData()") "foo.tmp" ;
+ numeric l ;
+ for i=1 step 1 until runscript("mp.MyDataSize()") :
+ l := length(runscript("mp.MyDataString()") i) ;
+ endfor ;
+ draw textext(decimal l);
\stopMPcode
-\stoplinecorrection
-
-You can also name your own hash:
+\stoptyping
-\startlinecorrection
-\startMPcode
-lua.mp.newhash("foo") ;
+In \LMTX\ we can add some more abstraction. Performance is about the same and
+sometimes a bit faster but that depends on extreme usage: you need thousands of
+call to notice.
-for i=1 upto 3 :
- lua.mp.tohash("foo",i,decimal sqrt(i)) ;
-endfor ;
+\starttyping
+\startluacode
+ local injectnumeric = mp.inject.numeric
+ local injectstring = mp.inject.string
+ local scannumeric = mp.scan.numeric
+ local scanstring = mp.scan.string
+ local MyData = { }
+ metapost.registerscript("LoadMyData", function()
+ MyData = string.splitlines(io.loaddata(scanstring()))
+ end)
+ metapost.registerscript("MyDataSize", function()
+ injectnumeric(#MyData)
+ end)
+ metapost.registerscript("MyDataString", function()
+ injectstring(MyData[scannumeric()] or "")
+ end)
+\stopluacode
+\stoptyping
-draw textext(lua.mp.fromhash("foo",2))
- ysized 1cm
- withcolor green ;
+We have the same scripts but we register them. At the \METAPOST\ end we resolve
+the registered scripts and then call \type {runscript} with the (abstract) numeric
+value:
-lua.mp.disposehash("foo")
+\starttyping
+\startMPcode{doublefun}
+ newscriptindex my_script_LoadMyData ;
+ newscriptindex my_script_MyDataSize ;
+ newscriptindex my_script_MyDataString ;
+
+ my_script_LoadMyData := scriptindex "LoadMyData" ;
+ my_script_MyDataSize := scriptindex "MyDataSize" ;
+ my_script_MyDataString := scriptindex "MyDataString" ;
+
+ runscript my_script_LoadMyData "foo.tmp" ;
+ numeric l ;
+ for i=1 step 1 until runscript my_script_MyDataSize :
+ l := length(my_script_MyDataString i) ;
+ endfor ;
+ draw textext(decimal l);
\stopMPcode
-\stoplinecorrection
+\stoptyping
-Although it might look like \METAPOST\ supports arrays the reality is that it
-doesn't really. There is a concept of suffixes but internally these are just a
-way to compose macros. The following test is one that is used in one of the
-\METAFUN\ modules written by Alan Braslau.
+This is of course nicer:
-\startlinecorrection
-\startMPcode
-path p, q[] ;
-
-if lua.mp.isarray(str q[1]) :
- fill fullcircle scaled 1cm withcolor red ;
- draw textext(lua.mp.prefix(str q[1])) withcolor white;
-else :
- fill fullsquare scaled 1cm withcolor blue ;
-fi ;
-
-currentpicture := currentpicture shifted (-2cm,0) ;
-
-if lua.mp.isarray(str p) :
- fill fullcircle scaled 1cm withcolor red ;
-else :
- fill fullsquare scaled 1cm withcolor blue ;
-fi ;
+\starttyping
+\startMPcode{doublefun}
+ def LoadMyData (expr s) = runscript my_script_LoadMyData s enddef ;
+ def MyDataSize = runscript my_script_MyDataSize enddef ;
+ def MyDataString(expr i) = runscript my_script_MyDataString i enddef ;
+
+ LoadMyData("foo.tmp") ;
+ numeric l ;
+ for i=1 step 1 until MyDataSize :
+ l := length(MyDataString(i)) ;
+ endfor ;
+ draw textext(decimal l);
\stopMPcode
-\stoplinecorrection
+\stoptyping
-Another helper relates to extensions that \METAFUN\ adds to \METAPOST. When you
-iterate over a picture you can recognize these as objects. The next code shows
-the \LUA\ call as well as the more convenient macro call. So, \type {textext}
-clearly is a foreign object.
+So, to sumarize, there are many ways to look at this: verbose direct ones
+but also nicely abstract ones.
-\startlinecorrection
-\startMPcode
-picture p ; p := image (
- fill fullcircle scaled 1cm withcolor red ;
- draw textext("ok") withcolor white ;
-) ;
-
-for i within p :
- if not picture i :
- draw i ysized 4cm ;
- elseif isobject i :
- draw i xsized 3cm ;
- else :
- draw i ysized 4cm ;
- fi ;
-endfor ;
+\stopsection
-currentpicture := currentpicture shifted (-6cm,0) ;
+% The plugins (like those dealing with text) also use calls in the \type {mp}
+% namespace but they have sort of protected names, starting with \type {mf_}. These
+% are visible but not meant to be used by users. Not only can their name change,
+% their functionality can as well.
+%
+% The following are actually private as they have related macros but also have a
+% public alias:
+%
+% \startlines
+% lua.mp.pathlength(name)
+% lua.mp.pathpoint(i)
+% lua.mp.pathleft(i)
+% lua.mp.pathright(i)
+% lua.mp.pathreset()
+% \stoplines
+%
+% They are meant for special high|-|performance path access, for example:
+%
+% \startlinecorrection
+% \startMPcode
+% save p, q, r;
+% path p ; p := for i=1 upto 1000 :
+% (i,0) -- (i,4 + uniformdeviate 4) --
+% endfor cycle ;
+% fill p xysized (TextWidth,20mm) withcolor red ;
+%
+% path q ; q := for i=1 upto lua.mp.pathlength("p") :
+% if (i mod 4) == 0 : lua.mp.pathpoint(i) -- fi
+% endfor cycle ;
+% fill q xysized (TextWidth,2cm) shifted (0,-45mm) withcolor green ;
+%
+% path r ; r := for i inpath p :
+% if not odd (i) : pointof i -- fi
+% endfor cycle ;
+% fill r xysized (TextWidth,2cm) shifted (0,-70mm) withcolor blue ;
+% \stopMPcode
+% \stoplinecorrection
+%
+% Because a lookup of a point in \METAPOST\ is a linear lookup over a linked list
+% for very large paths the gain is significant when using \LUA\ because there the
+% points are stored in an indexed table. The left and right points can be used
+% vebose like
+%
+% \starttyping
+% lua.mp.pathpoint(i) controls lua.mp.pathleft(i) and lua.mp.pathright(i)
+% \stoptyping
+%
+% or more terse:
+%
+% \starttyping
+% pointof i controls leftof i and rightof i
+% \stoptyping
+%
+% Beware: this kind of trickery is {\em only} needed when you have very large paths
+% that are to be manipulated and the. Otherwise it's overkill.
+%
+% \stopsection
+%
+% \startsection[title={Interfacing to \TEX}]
+%
+% The next bunch of calls is for accessing \TEX\ registers. You can set their
+% values and get them as well.
+%
+% \starttyping
+% lua.mp.getmacro(k)
+% lua.mp.getdimen(k)
+% lua.mp.getcount(k)
+% lua.mp.gettoks (k)
+%
+% lua.mp.setmacro(k,v)
+% lua.mp.setdimen(k,v)
+% lua.mp.setcount(k,v)
+% lua.mp.settoks (k,v)
+% \stoptyping
+%
+% When you mess around with variables and run into issues it might help to
+% report values on the console. The \type {report} function does this:
+%
+% \starttyping
+% lua.mp.report(a,b)
+% \stoptyping
+%
+% \startlinecorrection
+% \startMPcode
+% lua.mp.report("status","a circle") ;
+% fill fullcircle xyscaled (2cm,1cm) withcolor red ;
+% lua.mp.report("status","its boundingbox [@N,@N,@N,@N]",
+% xpart llcorner currentpicture, ypart llcorner currentpicture,
+% xpart urcorner currentpicture, ypart urcorner currentpicture
+% ) ;
+% draw boundingbox currentpicture withcolor blue ;
+% report("status","the size: @Nbp x @Nbp",
+% bbwidth(currentpicture), bbheight(currentpicture)
+% ) ;
+% message("done") ;
+% \stopMPcode
+% \stoplinecorrection
+%
+% The console shows:
+%
+% \starttyping
+% metapost > status : a circle
+% metapost > status : its boundingbox [-28.34645,-14.17323,28.34645,14.17323]
+% metapost > status : the size: 57.1929bp x 28.84647bp
+% metapost > message : done
+% \stoptyping
+%
+% There are two more getters. These can be used to access the specific graphic
+% related variables set at the \TEX\ end.
+%
+% \starttyping
+% mp.texvar(name)
+% mp.texstr(name)
+% \stoptyping
+%
+% If you have adaptive styles you might want to test for modes.
+%
+% \starttyping
+% if lua.mp.mode("screen") : % or processingmode
+% % some action only needed for screen documents
+% fi ;
+% if lua.mp.systemmode("first") :
+% % some action for the first run
+% fi ;
+% \stoptyping
+%
+% For convenience these are wrapped into macros:
+%
+% \starttyping
+% if texmode("screen") :
+% % some action only needed for screen documents
+% fi ;
+% if systemmode("first") :
+% % some action for the first run
+% fi ;
+% \stoptyping
+%
+% When you implement your own helpers you can fall back on some auxiliary functions
+% in the \type {mp} namespace. Actually these are collected in \type {mp.aux} and
+% thereby protected from being overwritten by mistake. Here they are:
+%
+% % mp.flush()
+% % mp.size(t)
+%
+% \stopsection
-for i within p :
- if isobject(i) :
- draw i xsized 5cm ;
- else :
- draw i ysized 3cm withcolor blue;
- fi ;
-endfor ;
-\stopMPcode
-\stoplinecorrection
+% \startsection[title={Interfacing to \METAPOST}]
+%
+% There is also experimental access to some of the \METAPOST\ internals. In order
+% to deal with (large) paths a few more iterator related helpers are provided too.
+%
+% % mp.set (numeric string path boolean)
+%
+% \starttyping
+% n = mp.getnumeric(name)
+% s = mp.getstring(name)
+% b = mp.getboolean(name)
+% p = mp.getpath(name)
+% \stoptyping
+%
+% A is path a table of tables that have six values: the coordinates and the
+% pre- and postcontrol. You can manipulate this table and feed it back into
+% \METAPOST.
+%
+% \startlinecorrection
+% \startMPcode
+% numeric n ; n := lua.mp.newhash() ;
+%
+% for i=1 upto 3 :
+% lua.mp.tohash(n,i) ;
+% endfor ;
+%
+% fill fullcircle scaled 10mm withcolor
+% if lua.mp.inhash(n,3) : green else : red fi ;
+%
+% fill fullcircle scaled 5mm withcolor
+% if lua.mp.inhash(n,4) : green else : red fi ;
+%
+% lua.mp.disposehash(n)
+% \stopMPcode
+% \stoplinecorrection
+%
+% You can also store values with keys and access them later:
+%
+% \startlinecorrection
+% \startMPcode
+% numeric n ; n := lua.mp.newhash() ;
+%
+% for i=1 upto 3 :
+% lua.mp.tohash(n,i,decimal sqrt(i)) ;
+% endfor ;
+%
+% draw textext(lua.mp.fromhash(n,3))
+% ysized 1cm
+% withcolor blue ;
+%
+% lua.mp.disposehash(n)
+% \stopMPcode
+% \stoplinecorrection
+%
+% You can also name your own hash:
+%
+% \startlinecorrection
+% \startMPcode
+% lua.mp.newhash("foo") ;
+%
+% for i=1 upto 3 :
+% lua.mp.tohash("foo",i,decimal sqrt(i)) ;
+% endfor ;
+%
+% draw textext(lua.mp.fromhash("foo",2))
+% ysized 1cm
+% withcolor green ;
+%
+% lua.mp.disposehash("foo")
+% \stopMPcode
+% \stoplinecorrection
+%
+% Although it might look like \METAPOST\ supports arrays the reality is that it
+% doesn't really. There is a concept of suffixes but internally these are just a
+% way to compose macros. The following test is one that is used in one of the
+% \METAFUN\ modules written by Alan Braslau.
+%
+% \startlinecorrection
+% \startMPcode
+% path p, q[] ;
+%
+% if lua.mp.isarray(str q[1]) :
+% fill fullcircle scaled 1cm withcolor red ;
+% draw textext(lua.mp.prefix(str q[1])) withcolor white;
+% else :
+% fill fullsquare scaled 1cm withcolor blue ;
+% fi ;
+%
+% currentpicture := currentpicture shifted (-2cm,0) ;
+%
+% if lua.mp.isarray(str p) :
+% fill fullcircle scaled 1cm withcolor red ;
+% else :
+% fill fullsquare scaled 1cm withcolor blue ;
+% fi ;
+% \stopMPcode
+% \stoplinecorrection
+%
+% Another helper relates to extensions that \METAFUN\ adds to \METAPOST. When you
+% iterate over a picture you can recognize these as objects. The next code shows
+% the \LUA\ call as well as the more convenient macro call. So, \type {textext}
+% clearly is a foreign object.
+%
+% \startlinecorrection
+% \startMPcode
+% picture p ; p := image (
+% fill fullcircle scaled 1cm withcolor red ;
+% draw textext("ok") withcolor white ;
+% ) ;
+%
+% for i within p :
+% if not picture i :
+% draw i ysized 4cm ;
+% elseif isobject i :
+% draw i xsized 3cm ;
+% else :
+% draw i ysized 4cm ;
+% fi ;
+% endfor ;
+%
+% currentpicture := currentpicture shifted (-6cm,0) ;
+%
+% for i within p :
+% if isobject(i) :
+% draw i xsized 5cm ;
+% else :
+% draw i ysized 3cm withcolor blue;
+% fi ;
+% endfor ;
+% \stopMPcode
+% \stoplinecorrection
% not yet, still experimental:
%
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-macros.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-macros.tex
index e1df13c92ac..969e7d1b169 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-macros.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-macros.tex
@@ -31,12 +31,13 @@ There are several ways to use the power of \METAFUN, either or not using
\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.
+ You can embed the graphic in a \type {\startMPpage} \unknown \type
+ {\stopMPpage} 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
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-reference.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-reference.tex
index 6eb177949be..bc59218b0cc 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-reference.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-reference.tex
@@ -476,7 +476,7 @@ defineshade cshade withshademethod "circular" ;
\ShowSampleJ {mm} {pencircle transform} {pencircle}
\ShowSampleJ {mm} {pensquare transform} {pensquare}
\ShowSampleJ {mm} {penrazor transform} {penrazor}
-\ShowSampleK {mm} {penspeck transform} {penspeck}
+\ShowSampleK {mm} {penspec transform} {penspec}
\ShowSampleL {mm} {draw} {fullcircle}
\ShowSampleL {mm} {fill} {fullcircle}
@@ -610,7 +610,7 @@ defineshade cshade withshademethod "circular" ;
\ShowSampleS {fm}
{externalfigure string ...}
- {draw externalfigure "mycow.pdf" scaled 3cm}
+ {draw externalfigure "mycow.pdf" ysized 3cm}
\ShowSampleT {fm} {addbackground text}
{addbackground withcolor .625 yellow}
@@ -637,11 +637,28 @@ defineshade cshade withshademethod "circular" ;
\ShowSampleT {mm}
{withmask string}
- {draw externalfigure "m-1.png" scaled 2cm withmask "m-2.png"}
+ {draw externalfigure "m-1.png" ysized 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"}
+ draw externalfigure "m-2.png" ysized 2cm shifted (-3cm,0) ;
+ draw externalfigure "m-1.png" ysized 2cm shifted (-6cm,0) ;
+ draw externalfigure "m-1.png" ysized 2cm withmask "m-2.png"}
+
+\stopsection
+
+\startsection[title={Access}]
+
+\ShowSampleW
+ {mm} {leftof n}
+ {for i inpath fullcircle : drawdot leftof i ; endfor}
+ {for i inpath fullcircle xsized 3cm: drawdot leftof i withpen pencircle scaled 2mm InRed ; endfor}
+\ShowSampleW
+ {mm} {pointof n}
+ {for i inpath fullcircle : drawdot pointof i ; endfor}
+ {for i inpath fullcircle xsized 3cm: drawdot pointof i withpen pencircle scaled 2mm InYellow ; endfor}
+\ShowSampleW
+ {mm} {rightof n}
+ {for i inpath fullcircle : drawdot rightof i ; endfor}
+ {for i inpath fullcircle xsized 3cm: drawdot rightof i withpen pencircle scaled 2mm InRed ; endfor}
\stopsection
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex
index 02c502cf01c..56bf5d4d61e 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex
@@ -22,12 +22,12 @@ 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
+ save s ; string s ; s := str @# ;
+ if length(s) > 0 :
+ textext(s)
+ else :
+ nullpicture
+ fi
enddef ;
\stoptyping
@@ -41,7 +41,7 @@ But if afterwards we say:
\starttyping
vardef bar(expr x) =
- 123
+ 123
enddef ;
\stoptyping
@@ -55,6 +55,141 @@ to store their meanings and allocate new ones after that inside the group.
\stopsection
+\startsection[title=Templates]
+
+This section is a bit off|-|topic and thereby also qualifies as sneaky. At the
+\TEX\ end we have a couple of alternative input methods, like \XML\ and templates.
+Just because we want to be consistent, the \METAPOST\ end also offers this.
+
+The first example resembled the \type{btex ... etex} approach:
+
+\startbuffer
+\startbuffer[test-a]
+ blua for i=0,100,20 do elua
+ draw fullcircle scaled (blua p(i) elua * cm)
+ withcolor "darkgreen" withpen pencircle scaled 1cm ;
+ blua end elua
+
+ blua for i=10,100,20 do elua
+ draw fullcircle scaled (blua p(i) elua * cm)
+ withcolor "darkred" withpen pencircle scaled 1cm ;
+ blua end elua
+\stopbuffer
+
+\startMPcode
+ draw image (
+ loadfile ("mpstemplate://buffer?name=test-a") ;
+ ) ysized 3cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[test-1][option=TEX]
+
+The filename is specified as a \URI\ and the \type {mpstemplate} does the magic
+here.
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+The second example is like the \type {lmx} files that you can find in the distibution:
+
+\startbuffer
+\startbuffer[test-b]
+ <?lua for i=0,100,20 do ?>
+ draw fullcircle scaled (<?lua p(i) ?> * cm)
+ withcolor "darkblue" withpen pencircle scaled 1cm ;
+ <?lua end ?>
+
+ <?lua for i=10,100,20 do ?>
+ draw fullcircle scaled (<?lua p(i) ?> * cm)
+ withcolor "darkyellow" withpen pencircle scaled 1cm ;
+ <?lua end ?>
+\stopbuffer
+
+\startMPcode
+ draw image (
+ loadfile ("mpstemplate://buffer?name=test-b") ;
+ ) ysized 3cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[test-b][option=TEX]
+
+The filename is again specified as a \URI:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startMPcode
+ picture p[] ; % we can't input nested
+ loadfile("mpstemplate://buffer?name=test-a&method=metapost") ;
+ p[1] := currentpicture ; currentpicture := nullpicture ;
+ loadfile("mpstemplate://buffer?name=test-b&method=xml") ;
+ p[2] := currentpicture ; currentpicture := nullpicture ;
+ draw p[1] ysized 3cm ;
+ draw p[2] ysized 4cm shifted (4cm,0) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The combination comes out as:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+Another approach is to load as image, which saves some typing:
+
+\startbuffer
+\startMPpage[offset=10pt]
+ draw image (loadfile("mpstemplate://buffer?name=test-a&method=metapost"))
+ xsized 2cm shifted ( 3cm,0) ;
+ draw image (loadfile("mpstemplate://buffer?name=test-b&method=xml"))
+ xsized 2cm shifted ( 6cm,0) ;
+ draw loadimage ("mpstemplate://buffer?name=test-a&method=metapost")
+ xsized 2cm shifted ( 9cm,0) ;
+ draw loadimage ("mpstemplate://buffer?name=test-b&method=xml")
+ xsized 2cm shifted (12cm,0) ;
+\stopMPpage
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The result is predictable:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+Of course there is also a \type {cld} approach possible:
+
+\startbuffer
+\startluacode
+ context.startMPcode() -- context.startMPpage { offset = "10pt" }
+ for i=0,100,20 do
+ context ( [[draw fullcircle scaled (%s * cm)
+ withcolor "darkmagenta" withpen pencircle scaled 1cm ;]], i)
+ end
+ for i=10,100,20 do
+ context ( [[draw fullcircle scaled (%s * cm)
+ withcolor "darkcyan" withpen pencircle scaled 1cm ;]], i)
+ end
+ context.stopMPcode() -- context.stoppage()
+\stopluacode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The commented commands will create a page. This is a convenient way to make
+graphics that can be used in other documents (programs). For practical reasons the
+example is scaled down:
+
+\startlinecorrection[blank] \scale[height=3cm]{\getbuffer} \stoplinecorrection
+
+All these methods are rather efficient because all happens in memory and without
+intermediate runs. It is this kind of features that the tight integration of \TEX,
+\METAPOST\ and \LUA\ make possible.
+
+\stoptext
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-styles.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-styles.tex
index f82359117a7..6de9a54daa2 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-styles.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-styles.tex
@@ -189,14 +189,14 @@ what lines we need in order to be calculate the button shapes.
\placefigure
[here][fig:style]
{The lines used to calculate the button shapes.}
- {\externalfigure[mfun-774.pdf][page=1,height=.85\textheight]}
+ {\typesetfile[mfun-774.tex][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]}}
+ {\rotate{\typesetfile[mfun-774.tex][page=1,height=\textwidth]}}
\stopnotmode
\page
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-text-lmtx.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-text-lmtx.tex
new file mode 100644
index 00000000000..abdca3c3ad0
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-text-lmtx.tex
@@ -0,0 +1,1519 @@
+% 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}
+
+The \METAPOST\ program is about graphics, not about text. Its ancestor was made
+for creating fonts and in order to do so, it actually had some limited
+capabilities to add text to a graphic, like coordinates to points. Now, when
+you really want to add typeset text, we need something more. The traditional way
+to add some text to a \METAPOST\ graphic was to use this:
+
+\starttyping
+btex Some text to be typeset by \TEX etex
+\stoptyping
+
+The machinery was set up in such a way that these snippets got delegated to \TEX,
+and the resulting \DVI\ converted back into a a \METAPOST\ picture with objects
+that refer to a font and character. Although the \METAPOST\ program could handle
+that by calling out to \TEX, we never used that method. In \MKII\ we had two
+flows: either direct processing, or collect all texts and process them between
+runs. Because the backend (conversion to \PDF) was under \CONTEXT\ control we
+could do more than usual. You can find some information in the older manuals.
+
+In \CONTEXT\ \MKIV\ we started using the library variant of \METAPOST. Its
+integration in \LUATEX\ made it possible to do all text rendering runtime at high
+speed. This change 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 loading 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.
+
+In \MKIV\ we still have two internal runs per \METAPOST\ graphic that has text:
+the first time the texts snippets are collected and afterwards handed over to
+\LUA\ that tells the \TEX\ ending to process it. The dimensions are saved and
+used in a second processing of the graphic. Contrary to \MKII\ the user doesn't
+see these two runs: they appear as one. In \in {figure} [fig:text:mkiv] this is
+illustrated.
+
+\startFLOWchart[mkiv]
+ \startFLOWcell
+ \name {metapost 1}
+ \location {1,1}
+ \shape {action}
+ \text {\METAPOST\ \type{textext 1}}
+ \connection [rl] {lua 1}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {lua 1}
+ \location {2,1}
+ \shape {action}
+ \text {\LUA}
+ \connection [rl] {context 1}
+ \connection [bb] {metapost 2}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {context 1}
+ \location {3,1}
+ \shape {action}
+ \text {\CONTEXT}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {metapost 2}
+ \location {4,1}
+ \shape {action}
+ \text {\METAPOST\ \type{textext 2}}
+ \connection [bb] {lua 1}
+ \connection [rl] {backend 1}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {backend 1}
+ \location {5,1}
+ \shape {action}
+ \text {backend}
+ \stopFLOWcell
+\stopFLOWchart
+
+In the later versions of \MKIV\ it was possible to jump out to \TEX\ immediately
+and save the second run, although there were cases where this was not possible
+(reliable). In \LMTX\ we always have one run. This is summarized in \in {figure}
+[fig:text:mkiv]. All this has to do with the fact that \TEX, \METAPOST\ and \LUA\
+are integrated but still kind of independent. When you expand a macro (that
+triggers processing of a graphic) you end up in a call to the \METAPOST\ library
+but \TEX\ is still in that macro. In \LUATEX\ and more advanced in \LUAMETATEX\
+you can sort of spawn a subprocess in \TEX\ (called local control) and indeed
+process the text immediately and use the calculated dimension after that has been
+done. All that \METAPOST\ needs is dimensions as it the backend that eventually
+will include the text.
+
+\startplacefigure[title={How \TEX\ and \METAPOST\ work together (\MKIV).},reference=fig:text:mkiv]
+ \FLOWchart[mkiv]
+\stopplacefigure
+
+\startFLOWchart[lmtx]
+ \startFLOWcell
+ \name {context 1}
+ \location {1,1}
+ \shape {action}
+ \text {\CONTEXT}
+ \connection [rl] {lua 1}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {lua 1}
+ \location {2,1}
+ \shape {action}
+ \text {\LUA}
+ \connection [lr] {context 1}
+ \connection [rl] {metapost 1}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {metapost 1}
+ \location {3,1}
+ \shape {action}
+ \text {\METAPOST\ \type{textext}}
+ \connection [lr] {lua 1}
+ \connection [rl] {backend 1}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {backend 1}
+ \location {5,1}
+ \shape {action}
+ \text {backend}
+ \stopFLOWcell
+\stopFLOWchart
+
+\startplacefigure[title={How \TEX\ and \METAPOST\ work together (\LMTX).},reference=fig:text:lmtx]
+ \FLOWchart[lmtx]
+\stopplacefigure
+
+\stopsection
+
+\startsection[title={Environments}]
+
+\index{environments}
+
+The \type {textext} command is the main text handling command and it is used in many places
+in this manual. It takes a string.
+
+In \MKII\ text was processed between runs or immediately but still by running an
+independent \TEX\ run. That has some consequences when the text was to share its
+properties with the main document. This means that in \MKII\ we pass
+characteristics of the layout, spacing, fonts, color and optionally an
+environment that a user has set up. This is mentioned in the older manual but no
+longer relevant in \MKIV\ and \LMTX. Because we handle the text runtime we
+automatically use the same style and document properties.
+
+This means that in code like the following, a Palatino font will be used because
+that is what we use in this document.
+
+\starttyping
+\startMPcode
+draw btex Meta is a female lion! etex xysized (TextWidth,TextHeight) ;
+\stopMPcode
+\stoptyping
+
+But even when we still support \type {btex} we strongly advise users to use this:
+
+\starttyping
+\startMPcode
+draw textext("Meta is a female lion!") xysized (TextWidth,TextHeight) ;
+\stopMPcode
+\stoptyping
+
+In this example as well in the next one you see that we access \type {TextWidth}
+directly. In older examples in the \CONTEXT\ distribution you will notice that we
+serialize \TEX\ registers like \type {\textwidth}. This is still valid but less
+preferable. Here \type {TextWidth} is actually a macro that calls out to \LUA\
+from where we fetch the value of \type {\textwidth} and pipe it back to
+\METAPOST\ in a way that makes it look like we have a variable.
+
+\startbuffer[lioncode]
+\startMPcode
+numeric w, h ; w := TextWidth ; h := w/2 ;
+
+picture p ; p := textext.urt("Meta is a female lion!") xysized (w,h) ;
+picture q ; q := textext.urt("Meta is a female lion!") xysized (w,h) ;
+
+path b ; b := boundingbox p ; draw p withcolor "darkyellow" ;
+
+draw textextanchor(p) withpen pencircle scaled 5mm withcolor "darkblue" ;
+
+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 withcolor "darkred";
+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.
+
+\startplacefigure[title={An example of clipping.},reference=lionclip]
+ \getbuffer[lioncode]
+\stopplacefigure
+
+In this example we show that the origin of the text. By default it gets centered
+but the \type {urt} suffix moves it. Here is another example of showing the
+origin:
+
+\startbuffer
+\startMPcode
+picture p ; p := thetextext.top("foo",(10,1));
+picture q ; q := thetextext.lft("foo",(1,10));
+
+draw textextanchor(p) withpen pencircle scaled 2mm withcolor "darkred" ;
+draw textextanchor(q) withpen pencircle scaled 1mm withcolor "white" ;
+
+draw p;
+draw q;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+It gives the following:
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+\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).
+
+Normally you can stick to the default and forget about these details. More important
+is how you anchor labels. This is best shown with some examples:
+
+\startbuffer
+\startMPcode
+ path p ; p := fullcircle scaled 3cm ;
+
+ drawarrow p ;
+
+ dotlabel ("test",point 0 of p) withcolor red ;
+ dotlabel.rt ("rt", point 1 of p) ;
+ dotlabel.urt ("urt", point 2 of p) ;
+ dotlabel.top ("top", point 3 of p) ;
+ dotlabel.ulft("ulft",point 4 of p) ;
+ dotlabel.lft ("lft", point 5 of p) ;
+ dotlabel.llft("llft",point 6 of p) ;
+ dotlabel.bot ("bot", point 7 of p) ;
+ dotlabel.lrt ("lrt", point 8 of p) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startMPcode
+ path p ; p := fullcircle scaled 3cm ;
+
+ drawarrow p ;
+
+ dotlabel ("test",p) ;
+ dotlabel.rt ("rt", p) ;
+ dotlabel.urt ("urt", p) ;
+ dotlabel.top ("top", p) ;
+ dotlabel.ulft("ulft",p) ;
+ dotlabel.lft ("lft", p) ;
+ dotlabel.llft("llft",p) ;
+ dotlabel.bot ("bot", p) ;
+ dotlabel.lrt ("lrt", p) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startMPcode
+ p := (origin..right..up..left) scaled 3cm ;
+
+ drawarrow p ;
+
+ label ("test",p) ;
+ label.rt ("rt", p) ;
+ label.urt ("urt", p) ;
+ label.top ("top", p) ;
+ label.ulft("ulft",p) ;
+ label.lft ("lft", p) ;
+ label.llft("llft",p) ;
+ label.bot ("bot", p) ;
+ label.lrt ("lrt", p) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startMPcode
+ picture p ; p := image(drawarrow (origin..right..up..left) scaled 3cm ;) ;
+
+ draw p ;
+ draw bbox p dashed evenly ;
+
+ label ("test",p) ;
+ label.rt ("rt", p) ;
+ label.urt ("urt", p) ;
+ label.top ("top", p) ;
+ label.ulft("ulft",p) ;
+ label.lft ("lft", p) ;
+ label.llft("llft",p) ;
+ label.bot ("bot", p) ;
+ label.lrt ("lrt", p) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startMPcode
+ picture p ; p := image(drawarrow (origin..right..up..left) scaled 3cm ;) ;
+
+ draw p ;
+ draw bbox p dashed evenly ;
+
+ draw textext ("test") shifted theoffset (p) ;
+ draw textext.lft ("rt") shifted theoffset.rt (p) ;
+ draw textext.llft("urt") shifted theoffset.urt (p) ;
+ draw textext.bot ("top") shifted theoffset.top (p) ;
+ draw textext.lrt ("ulft") shifted theoffset.ulft(p) ;
+ draw textext.rt ("lft") shifted theoffset.lft (p) ;
+ draw textext.urt ("llft") shifted theoffset.llft(p) ;
+ draw textext.top ("bot") shifted theoffset.bot (p) ;
+ draw textext.ulft("lrt") shifted theoffset.lrt (p) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\stopsection
+
+\startsection[title={Text along a path}]
+
+\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]
+ \startitem
+ the text should be properly kerned, i.e.\ the spacing between characters
+ should be optimal,
+ \stopitem
+ \startitem
+ the position on the circle should vary, and
+ \stopitem
+ \startitem
+ the radius of the circle should vary.
+ \stopitem
+\stopitemize
+
+This code below is a bit rusted but it illustrates the principles. In \MKIV\ and
+\LMTX\ we have typesetting along a curve built in so we no longer show the \TEX\
+code that integrates it. This implementation is not the most straightforward one,
+but by doing it step by step, at least we see what is involved.
+
+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
+{[-]}. This code is presented as an example of how these mechanissm evolved in
+\CONTEXT.
+
+\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.
+
+Next we show how it is done today in \LMTX. Instead of wrapping it in a macro we
+just do all in \METAPOST. Watch how we use the key|/|value interface:
+
+\startbuffer
+\startMPcode
+ draw lmt_followtext [
+ path = halfcircle rotated 45 scaled 4cm,
+ text = "Does it work ok?",
+ spread = true,
+ trace = true,
+ ] ;
+ draw lmt_followtext [
+ path = halfcircle rotated -30 scaled 3cm,
+ text = "Does it work ok?",
+ spread = false,
+ trace = true,
+ ] shifted (4cm,0) ;
+ draw lmt_followtext [
+ path = reverse halfcircle scaled 2cm,
+ text = "Does it work ok?",
+ spread = true,
+ trace = true,
+ ] shifted (8cm,0) ;
+\stopMPcode
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Using shapes}]
+
+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}
+ MyOffset := LineHeight/2 ;
+ MyTopSkip := 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-2MyOffset)/hsize)
+ yscaled ((vsize-2MyOffset)/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 {MyTopSkip}, 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,-MyTopSkip) ;
+ 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=MyTopSkip step LineHeight 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<LineHeight) :
+ vvsize := vsize ;
+ else :
+ vvsize := (vsize div LineHeight) * LineHeight ;
+ fi ;
+
+ for i=MyTopSkip step LineHeight 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}
+MyOffset := .5LineHeight ;
+MyTopSkip := StrutHeight ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+Now that we know a bit how this works we demonstrate the implementation in \LMTX.
+Where in \MKIV\ and \MKII\ we let \METAPOST\ pass the dimensions to \TEX\ via a
+temporary file in \LMTX\ we communicate more directly. You can take a look at the
+source code if you want to know how that works.
+
+We start by defining 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 {lmt_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 (aka topskip). The
+height and depth of a line are often called strut height and depth, with a strut
+being an invisible character with maximum dimensions. Variables like \type
+{StrutHeight} refer to values at the \TEX\ end. We play safe and group so that we
+can save variables.
+
+\startbuffer
+\startuseMPgraphic{shapetest-1}
+ begingroup ;
+ save p ; path p ; p := fullcircle scaled 6cm ;
+ lmt_parshape [
+ path = p,
+ offset = BodyFontSize/2,
+ dx = 0, % default
+ dy = 0, % default
+ lineheight = LineHeight, % default
+ strutheight = StrutHeight, % default
+ strutdepth = StrutDepth, % default
+ topskip = StrutHeight, % default
+ ] ;
+ draw p withpen pencircle scaled 1pt ;
+ endgroup ;
+\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{shapetest-2}
+ begingroup ;
+ save p ; path p ; p := fullsquare rotated 45 scaled 5cm ;
+ lmt_parshape [
+ path = p,
+ offset = BodyFontSize/2,
+ trace = true,
+ ] ;
+ draw p withpen pencircle scaled 1pt ;
+ endgroup ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The third and fourth shape demonstrate that providing a suitable offset is not
+always trivial.
+
+\startbuffer
+\startuseMPgraphic{shapetest-3}
+ begingroup ;
+ save w, h, p ; path p ; w := h := 6cm ;
+ p := (.5w,h) -- ( 0, h) -- (0,0) -- (w,0) &
+ ( w,0) .. (.75w,.5h) .. (w,h) & (w,h) -- cycle ;
+ lmt_parshape [
+ path = p,
+ offset = BodyFontSize/2,
+ ] ;
+ draw p withpen pencircle scaled 1pt ;
+ endgroup ;
+\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{shapetest-4}
+ begingroup ;
+ save d, p, q, shape ; path p, q ; d := BodyFontSize/2;
+ vardef shape(expr w, h, o) =
+ (o,o) -- (w-o,o) & (w-o,o) .. (.75w-o,.5h) ..
+ (w-2o,h-o) & (w-2o,h-o) -- (o,h-o) -- cycle
+ enddef ;
+ p := shape(6cm, 6cm, d) ;
+ q := shape(6cm, 6cm, 0) ;
+ lmt_parshape [
+ path = p,
+ offsetpath = q,
+ dx = d,
+ dy = d,
+ trace = true,
+ ] ;
+ draw q withpen pencircle scaled 1pt ;
+ endgroup ;
+\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[shapetest-1][\useMPgraphic{shapetest-1}]
+\defineoverlay[shapetest-2][\useMPgraphic{shapetest-2}]
+\defineoverlay[shapetest-3][\useMPgraphic{shapetest-3}]
+\defineoverlay[shapetest-4][\useMPgraphic{shapetest-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[shapetest-1,shapetest-2,shapetest-3,shapetest-4]
+ \forgetall % as it says
+ \setupalign[verytolerant,stretch,normal]%
+ \samplefile{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 normal result is shown in \in {figure} [fig:shapes].
+
+\startbuffer[shapes]
+\startbuffer
+\startcombination[2*2]
+ {\framed[offset=overlay,frame=off,background=shapetest-1]{\getshapetext}} {shapetest-1}
+ {\framed[offset=overlay,frame=off,background=shapetest-2]{\getshapetext}} {shapetest-2}
+ {\framed[offset=overlay,frame=off,background=shapetest-3]{\getshapetext}} {shapetest-3}
+ {\framed[offset=overlay,frame=off,background=shapetest-4]{\getshapetext}} {shapetest-4}
+\stopcombination
+\stopbuffer
+\stopbuffer
+
+\typebuffer[shapes]
+
+\getbuffer[shapes]
+
+By using a buffer we keep \type {\placefigure} readable. You might have noticed
+that for two shapes we turned on tracing.
+
+\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]}
+
+\blank
+
+We can combine all those tricks, although the input is somewhat fuzzy. First we
+define a quote typeset in a circular paragraph shape where we use the defaults.
+
+\startbuffer[shape]
+\startuseMPgraphic{center}
+ lmt_parshape [
+ path = fullcircle scaled 8cm,
+ ]
+\stopuseMPgraphic
+
+\startshapetext[center]
+ \samplefile{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
+\startuseMPgraphic{circle}
+ save p ; path p ;
+ p := reverse fullcircle rotatedaround(origin,90)
+ xscaled OverlayWidth yscaled OverlayHeight ;
+
+ draw lmt_followtext [
+ path = p,
+ text = "This is just a dummy text, kerned by \TeX\ and typeset
+ in a circle using \MetaPost.\quad",
+ spread = true,
+ trace = true,
+ ] ;
+
+% draw p ;
+\stopuseMPgraphic
+
+\defineoverlay[edge][\useMPgraphic{circle}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The text and graphics come together in a framed text:
+
+\startbuffer
+\startplacefigure[title={One more time Hofstadter's quotation (normal).}]
+ \getbuffer[shape,quote]%
+ \framed
+ [offset=24pt,
+ background=edge,
+ frame=off,
+ backgroundoffset=-18pt]
+ {\getshapetext}
+\stopplacefigure
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-text.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-text.tex
index f70f53ac306..8229e35db46 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-text.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-text.tex
@@ -1,4 +1,4 @@
-% language=uk
+% engine=luatex language=uk
%
% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
@@ -48,7 +48,7 @@ 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
+this document takes 18 seconds (14.5 with \LUAJITTEX) and that includes loading 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.
@@ -680,7 +680,7 @@ in \MKIV\ we use a different approach. There we use a mix of \TEX, \METAPOST, an
\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]
+\useMPlibrary[txt]
So, how does this compare to earlier results? The original, full text as typeset
by \TEX, looks like:
@@ -974,11 +974,8 @@ 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 ;
+ MyOffset := LineHeight/2 ;
+ MyTopSkip := StrutHeight ;
\stopuseMPgraphic
\stopbuffer
@@ -999,8 +996,8 @@ dimensions.
hsize := xpart lrcorner p - xpart llcorner p ;
vsize := ypart urcorner p - ypart lrcorner p ;
- q := p xscaled ((hsize-2offset)/hsize)
- yscaled ((vsize-2offset)/vsize) ;
+ q := p xscaled ((hsize-2MyOffset)/hsize)
+ yscaled ((vsize-2MyOffset)/vsize) ;
hsize := xpart lrcorner q - xpart llcorner q ;
vsize := ypart urcorner q - ypart lrcorner q ;
@@ -1061,7 +1058,7 @@ Then we use \type {\useMPgraphic{text}} to call up the picture.
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
+We lower the top edge of \type {q}'s bounding box by \type {MyTopSkip}, 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.
@@ -1069,8 +1066,8 @@ we raise the bottom edge and cut off the pieces that fall below this line.
\startuseMPgraphic{text cutoff}
path tt, bb ;
- tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ;
- bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ;
+ tt := (ulcorner q -- urcorner q) shifted (0,-MyTopSkip) ;
+ bb := (llcorner q -- lrcorner q) shifted (0,StrutDepth) ;
l := l cutbefore (l intersectionpoint tt) ;
l := l cutafter (l intersectionpoint bb) ;
@@ -1120,18 +1117,18 @@ line has a height and depth, we have to determine which part touches first.
\startuseMPgraphic{text calc}
vardef found_point (expr lin, pat, sig) =
pair a, b ;
- a := pat intersection_point (lin shifted (0,strutheight)) ;
+ a := pat intersection_point (lin shifted (0,StrutHeight)) ;
if intersection_found :
- a := a shifted (0,-strutheight) ;
+ a := a shifted (0,-StrutHeight) ;
else :
a := pat intersection_point lin ;
fi ;
- b := pat intersection_point (lin shifted (0,-strutdepth)) ;
+ b := pat intersection_point (lin shifted (0,-StrutDepth)) ;
if intersection_found :
if sig :
- if xpart b > xpart a : a := b shifted (0,strutdepth) fi ;
+ if xpart b > xpart a : a := b shifted (0,StrutDepth) fi ;
else :
- if xpart b < xpart a : a := b shifted (0,strutdepth) fi ;
+ if xpart b < xpart a : a := b shifted (0,StrutDepth) fi ;
fi ;
fi ;
a
@@ -1153,7 +1150,7 @@ subpath).
\startuseMPgraphic{text step}
path line; pair lll, rrr ;
- for i=topskip step baselineskip until vsize :
+ for i=MyTopSkip step LineHeight until vsize :
line := (ulcorner q -- urcorner q) shifted (0,-i) ;
@@ -1165,17 +1162,17 @@ subpath).
\typebuffer \getbuffer
Here we divide the available space in lines. The first line starts at \type
-{strutheight} from the top.
+{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 ;
+ 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 ;
@@ -1214,13 +1211,13 @@ we get better results when we (on purpose) take a smaller height.
\startuseMPgraphic{text step}
path line; pair lll, rrr ; numeric vvsize ;
- if (strutheight+strutdepth<baselineskip) :
+ if (StrutHeight+StrutDepth<LineHeight) :
vvsize := vsize ;
else :
- vvsize := (vsize div baselineskip) * baselineskip ;
+ vvsize := (vsize div LineHeight) * LineHeight ;
fi ;
- for i=topskip step baselineskip until vvsize :
+ for i=MyTopSkip step LineHeight until vvsize :
line := (ulcorner q -- urcorner q) shifted (0,-i) ;
@@ -1240,11 +1237,8 @@ better) results.
\startbuffer
\startuseMPgraphic{text vars}
-baselineskip := 8pt ;
-strutheight := 4pt ;
-strutdepth := 2pt ;
-offset := 4pt ;
-topskip := 3pt ;
+MyOffset := .5LineHeight ;
+MyTopSkip := StrutHeight ;
\stopuseMPgraphic
\stopbuffer
@@ -1261,8 +1255,8 @@ this is to let \METAPOST\ write a \type {\parshape} specification.
\startbuffer
\startuseMPgraphic{text macro}
- def provide_parshape (expr p, offset, baselineskip,
- strutheight, strutdepth, topskip) =
+ def provide_parshape (expr p, MyOffset, LineHeight,
+ StrutHeight, StrutDepth, MyTopSkip) =
\includeMPgraphic{text move}
\includeMPgraphic{text split}
@@ -1285,13 +1279,13 @@ the loop we write those values to a file using another loop.
\startuseMPgraphic{text loop}
path line; pair lll, rrr ; numeric vvsize, n ; n := 0 ;
- if (strutheight+strutdepth<baselineskip) :
+ if (StrutHeight+StrutDepth<LineHeight) :
vvsize := vsize ;
else :
- vvsize := (vsize div baselineskip) * baselineskip ;
+ vvsize := (vsize div LineHeight) * LineHeight ;
fi ;
- for i=topskip step baselineskip until vvsize :
+ for i=MyTopSkip step LineHeight until vvsize :
line := (ulcorner q -- urcorner q) shifted (0,-i) ;
@@ -1327,12 +1321,12 @@ We can call this macro using the part we used in the previous examples.
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
+ (p, % shape path
+ .5*LineHeight, % offset
+ LineHeight, % distance between lines
+ StrutHeight, % height of a line
+ StrutDepth, % depth of a line
+ StrutHeight) ; % height of first line
\stopuseMPgraphic
\stopbuffer
@@ -1348,9 +1342,6 @@ macro gets the value of the graphic at hand.
\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.
@@ -1389,23 +1380,22 @@ able to handle multiple shapes at once, like the next example demonstrates.
\index{graphics+libraries}
-The macro discussed in the previous section is included in one of the \METAPOST\
-libraries, so we first have to say:
+In \MKIV\ and \LMTX\ the \METAFUN\ driven text around a curve is a core
+functionality. In \LMTX\ the specific paragraph shape are available in the core
+too. Otherwise you need to load a module:
\startbuffer
\useMPlibrary[txt]
\stopbuffer
-\typebuffer
-
-\getbuffer
+\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
+of the line, and the height of the first line (MyTopSkip 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.
@@ -1413,8 +1403,8 @@ being an invisible character with maximum dimensions.
\startuseMPgraphic{test 1}
path p ; p := fullcircle scaled 6cm ;
- build_parshape(p,6pt,0,0,\baselinedistance,
- \strutheight,\strutdepth,\strutheight) ;
+ build_parshape(p,6pt,0,0,LineHeight,
+ StrutHeight,StrutDepth,StrutHeight) ;
draw p withpen pencircle scaled 1pt ;
\stopuseMPgraphic
@@ -1429,8 +1419,8 @@ suits the small lines at the top and bottom.
\startuseMPgraphic{test 2}
path p ; p := fullsquare rotated 45 scaled 5cm ;
- build_parshape(p,6pt,0,0,\baselinedistance,
- \strutheight,\strutdepth,\strutheight) ;
+ build_parshape(p,6pt,0,0,LineHeight,
+ StrutHeight,StrutDepth,StrutHeight) ;
draw p withpen pencircle scaled 1pt ;
\stopuseMPgraphic
@@ -1447,8 +1437,8 @@ always trivial.
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) ;
+ build_parshape(p,6pt,0,0,LineHeight,
+ StrutHeight,StrutDepth,StrutHeight) ;
draw p withpen pencircle scaled 1pt ;
\stopuseMPgraphic
@@ -1472,8 +1462,8 @@ needed, since we need these later on.
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) ;
+ build_parshape(p,q,6pt,6pt,LineHeight,
+ StrutHeight,StrutDepth,StrutHeight) ;
draw q withpen pencircle scaled 1pt ;
\stopuseMPgraphic
@@ -1514,14 +1504,11 @@ set to the current shape dimensions. The normal result is shown in \in {figure}
\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}
+ {\framed[offset=overlay,frame=off,background=test 1]{\getshapetext}} {test 1}
+ {\framed[offset=overlay,frame=off,background=test 2]{\getshapetext}} {test 2}
+ {\framed[offset=overlay,frame=off,background=test 3]{\getshapetext}} {test 3}
+ {\framed[offset=overlay,frame=off,background=test 4]{\getshapetext}} {test 4}
\stopcombination
\stopbuffer
\stopbuffer
@@ -1591,8 +1578,8 @@ 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) ;
+ build_parshape(fullcircle scaled 8cm,0,0,0,LineHeight,
+ StrutHeight,StrutDepth,StrutHeight) ;
\stopuseMPgraphic
\startshapetext[center]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-welcome.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-welcome.tex
index 425d1579611..725d03756c4 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-welcome.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun-welcome.tex
@@ -3497,6 +3497,70 @@ line properties.
\stopsection
+\startsection[title={\UTF8}]
+
+The \METAPOST\ library used in \LUATEX\ and \LUAMETATEX\ supports \UTF8\ input.
+Actually there is not much magic needed to do this because all the engine in
+interested in is bytes and some just have a special meaning (like parenthesis,
+symbols that have a meaning in formulas etc).
+
+\startbuffer
+save p ; pen p ; p := currentpen ;
+pickup pencircle scaled .05;
+
+picture ○ ; ○ := image (draw fullcircle) ;
+picture ◎ ; ◎ := image (draw fullcircle ; draw fullcircle scaled .5) ;
+
+draw ◎ ysized 2cm withcolor darkblue ;
+draw ○ xsized 2cm shifted (3cm,0) withcolor darkgreen ;
+draw ○ xysized (3cm,2cm) shifted (7cm,0) withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+Here we use a \UTF8\ encoded character as macro name and the next image
+demonstrate that it does work indeed:
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+You can do crazy things like use emoji for special operators
+
+\startbuffer
+def ✏ = withpen pencircle enddef ;
+def ✖️ = scaled enddef ;
+fill fullsquare ✖️ 1cm ✏ ✖️ 1mm withcolor darkgray ;
+draw fullsquare ✖️ 1cm ✏ ✖️ 1mm withcolor darkblue ;
+\stopbuffer
+
+\typebuffer
+
+But do we really want to go there?
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Normally using \UTF8\ makes more sense in text or regular macro names, so if you
+want to use accented characters it is possible:
+
+\startbuffer
+def rændömîzèd = randomized 1/10 enddef ;
+
+draw textext ("\strut rændömîzèd") ;
+draw boundingbox currentpicture rændömîzèd
+ enlarged 2mm
+ withpen pencircle scaled 1mm
+ withcolor darkgreen ;
+\stopbuffer
+
+\typebuffer
+
+\page[preference]
+
+it really does work:
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun.tex b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun.tex
index dc90bb61157..6739b1ed537 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/metafun/metafun.tex
@@ -28,19 +28,21 @@
%
% 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.
+%
+% comment : Before I started updating the manual to lmtx (luametafun) I made sure that it
+% processed okay in the february 2021 version of lmtx. The runtime for 448 pages
+% (which is 20 more than the previous test) is some 16.5 seconds (just below 16
+% with compact fonts). So we can safely conclude that we're not worse off with
+% respect to performance. (I use the same machine.)
-\enabledirectives[hyphenator.optimize]
-\enabledirectives[hyphenator.flatten]
-% \setuphyphenation[method=traditional]
+% \enableexperiments[fonts.compact]
-% \enabletrackers[*defin*]
+% \enablemode[optional]
% \enablemode[screen]
\enablemode[print]
% \enablemode[book]
-% \usemodule[luacalls]
-
% todo: check startintro .. stopintro each chapter
% \showframe
@@ -75,7 +77,11 @@
\component metafun-gadgets
\component metafun-effects
\component metafun-functions
+\ifcase\contextlmtxmode
\component metafun-text
+\else
+ \component metafun-text-lmtx
+\fi
\component metafun-debugging
\component metafun-styles
\component metafun-examples
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-environment.tex b/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-environment.tex
index 3472f3b047e..bcbfa085123 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-environment.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-environment.tex
@@ -8,6 +8,8 @@
\usemodule[timing]
+\usemodule[obsolete-tokens]
+
\useMPlibrary[dum]
\dontcomplain
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-memory.tex b/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-memory.tex
index 4c16e613e59..f8259c7db31 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-memory.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-memory.tex
@@ -131,10 +131,10 @@ If you want to run such tests yourself, you need to load a module at startup:
The graphics can be generated with:
\starttyping
-\def\ShowUsage {optional filename}
-\def\ShowNamedUsage {optional filename}{red graphic}{blue graphic}
-\def\ShowMemoryUsage{optional filename}
-\def\ShowNodeUsage {optional filename}
+\ShowUsage {optional filename}
+\ShowNamedUsage {optional filename}{red graphic}{blue graphic}
+\ShowMemoryUsage{optional filename}
+\ShowNodeUsage {optional filename}
\stoptyping
(This interface may change.)
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-punk.tex b/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-punk.tex
index 3502736deec..1220815465d 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-punk.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-punk.tex
@@ -1,5 +1,8 @@
% language=uk
+% This only works in MKIV because in LMTX we don't load the font-vir module
+% any longer. No one used it anyway.
+
\environment mk-environment
\startcomponent mk-punk
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-tokenspeak.tex b/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-tokenspeak.tex
index 590dbba433a..8382f5cfcc9 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-tokenspeak.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/mk/mk-tokenspeak.tex
@@ -212,7 +212,7 @@ The result looks like: \ctxlua {
tokens.letters("12345"),
tokens.egroup,
}
- tex.printlist (t)
+ tex.printlist(t)
tokens.collectors.show(t)
}
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-style.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-style.tex
index 5ed934f2fb2..a85960bdddd 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-style.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-style.tex
@@ -43,12 +43,15 @@
\hss
% title
#2
- \doifmode {*sectionnumber} {
- % distance
- \hskip10mm
- % number
- \struttedbox{\offset[x=-1mm,y=2.5mm]{\scale[height=2cm]{#1}}}
- }
+ % \ifnum\getsomestructurenumber{\currentstructurelevel}{last}>\plusone
+ \ifnum\somenamedheadnumber{chapter}{last}>\plusone
+ \doifmode {*sectionnumber} {
+ % distance
+ \hskip10mm
+ % number
+ \struttedbox{\offset[x=-1mm,y=2.5mm]{\scale[height=2cm]{#1}}}
+ }
+ \fi
}
\stoptexdefinition
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/primitives/primitives.tex b/Master/texmf-dist/doc/context/sources/general/manuals/primitives/primitives.tex
new file mode 100644
index 00000000000..81b42c5b6c2
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/primitives/primitives.tex
@@ -0,0 +1,2378 @@
+% language=us
+
+% The usual time stamp. This written while listening intermized to Fish (just ran
+% into), Lazulli (some yt videos too, looking forward to a next live act) and
+% because this all is boring checking out Sarah Coopers channel for new DT syncs
+% every few hours.
+
+% When you feel unhappy about the lack of detail in this manual, just keep in mind
+% that you cannot really demand anything from volunteers: just hope for more (or
+% pay for it). Friendly comments and corrections are of course always welcome. As
+% we like what we're doing here, it all might eventually evolve to perfection, stay
+% tuned.
+%
+% Hans Hagen | j.hagen @ xs4all . nl | ntg-context @ ntg . nl
+
+\usemodule[article-basic]
+\usemodule[abbreviations-logos]
+\usemodule[scite]
+
+\definecolor[maincolor][darkblue]
+\definecolor[primcolor][darkblue]
+\definecolor[nonecolor][darkgray]
+
+\setuptyping
+ [option=tex]
+
+\setuptype
+ [option=tex]
+
+\setuphead
+ [subject]
+ [color=maincolor]
+
+\definehead
+ [newprimitive]
+ [section]
+ [color=maincolor]
+
+\definehead
+ [oldprimitive]
+ [section]
+ [color=nonecolor]
+
+\setuplist
+ [newprimitive]
+ [textcolor=maincolor]
+
+\setuplist
+ [oldprimitive]
+ [textcolor=nonecolor]
+
+\starttext
+
+\startMPpage
+ fill Page
+ withcolor "darkgray" ;
+ draw textext("\sstf {\white new} primitives")
+ xysized (.9bbwidth(Page),bbheight(Page)-2cm)
+ shifted center Page
+ withcolor "maincolor" ;
+ draw textext.ulft("\sstf in luametatex")
+ xysized (.9bbwidth(Page)/3,(bbheight(Page)-2cm)/6)
+ shifted center lrcorner Page
+ shifted (-.1bbwidth(Page),.05bbwidth(Page))
+ withcolor "white" ;
+ setbounds currentpicture to Page ;
+\stopMPpage
+
+\startsubject[title={Introduction}]
+
+Here I will discuss some of the new primitives in \LUATEX\ and \LUAMETATEX, the
+later being a successor that permits the \CONTEXT\ folks to experiment with new
+features. The order is arbitrary. When you compare \LUATEX\ with \PDFTEX, there
+are actually quite some differences. Some primitives that \PDFTEX\ introduced
+have been dropped in \LUATEX\ because they can be done better in \LUA. Others
+have been promoted to core primitives that no longer have a \type {pdf} prefix.
+Then there are lots of new primitives, some introduce new concepts, some are a
+side effect of for instance new math font technologies, and then there are those
+that are handy extensions to the macro language. The \LUAMETATEX\ engine drops
+quite some primitives, like those related to \PDFTEX\ specific font or backend
+features. It also adds some new primitives, mostly concerning the macro language.
+
+We also discuss the primitives that fit into the macro programming scope that are
+present in traditional \TEX\ and \ETEX\ but there are for sure better of
+descriptions out there already. Primitives that relate to typesetting, like those
+controlling math, fonts, boxes, attributes, directions, catcodes, \LUA\
+(functions) etc are not discussed here.
+
+There are for instance primitives to create aliases to low level registers like
+counters and dimensions, as well as other (semi|-|numeric) quantities like
+characters, but normally these are wrapped into high level macros so that
+definitions can't clash too much. Numbers, dimensions etc can be advanced,
+multiplied and divided and there is a simple expression mechanism to deal with
+them. These are not discussed here.
+
+\startcolumns
+ \placelist
+ [newprimitive,oldprimitive]
+ [alternative=c]
+\stopcolumns
+
+In this document the section titles that discuss the \color [nonecolor] {original
+\TEX\ and \ETEX\ primitives} have a different color those explaining the \color
+[primcolor] {\LUATEX\ and \LUAMETATEX\ primitives}.
+
+\stopsubject
+
+\page
+
+% When writing this manual I also decided to merge some of the condition related
+% code so that it dealt a bit more natural with the newer features. A usual side
+% effects if writing manuals.
+
+% \startoldprimitive[title={\tex {meaning}}]
+% \stopoldprimitive
+%
+% \startoldprimitive[title={\tex {par}}]
+% \stopoldprimitive
+%
+% \startoldprimitive[title={\tex {linepar}}]
+% \stopoldprimitive
+
+\startoldprimitive[title={\tex {afterassignment}}]
+
+The token following \type {\afterassignment}, a traditional \TEX\ primitive, is
+saved and gets injected (and then expanded) after a following assignment took
+place.
+
+\startbuffer
+\afterassignment !\def\MyMacro {}\quad
+\afterassignment !\let\MyMacro ?\quad
+\afterassignment !\scratchcounter 123\quad
+\afterassignment !%
+\afterassignment ?\advance\scratchcounter by 1
+\stopbuffer
+
+\typebuffer
+
+The \type {\afterassignment}s are not accumulated, the last one wins:
+
+{\getbuffer}
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {afterassigned}}]
+
+The \type {\afterassignment} primitive stores a token to be injected (and thereby
+expanded) after an assignment has happened. Unlike \type {\aftergroup}, multiple
+calls are not accumulated, and changing that would be too incompatible. This is
+why we have \type {\afterassigned}, which can be used to inject a bunch of
+tokens. But in order to be consistent this one is also not accumulative.
+
+\startbuffer
+\afterassigned{done}%
+\afterassigned{{\bf done}}%
+\scratchcounter=123
+\stopbuffer
+
+\typebuffer
+
+results in: \inlinebuffer\ being typeset.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {aftergroup}}]
+
+The traditional \TEX\ \type {\aftergroup} primitive stores the next token and
+expands that after the group has been closed.
+
+\startbuffer
+before{ ! \aftergroup a\aftergroup f\aftergroup t\aftergroup e\aftergroup r}
+\stopbuffer
+
+Multiple \type {\aftergroup}s are combined:
+
+\typebuffer
+
+\getbuffer
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {aftergrouped}}]
+
+The in itself powerful \type {\aftergroup} primitives works quite well, even
+if you need to do more than one thing: you can either use it multiple times, or
+you can define a macro that does multiple things and apply that after the group.
+However, you can avoid that by using this primitive which takes a list of tokens.
+
+\startbuffer
+regular
+\bgroup
+\aftergrouped{regular}%
+\bf bold
+\egroup
+\stopbuffer
+
+\typebuffer
+
+Because it happens after the group, we're no longer typesetting in bold.
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {atendofgroup}}]
+
+The token provided will be injected just before the group ends. Because
+these tokens are collected, you need to be aware of possible interference
+between them. However, normally this is managed by the macro package.
+
+\startbuffer
+\bgroup
+\atendofgroup\unskip
+\atendofgroup )%
+(but it works okay
+\egroup
+\stopbuffer
+
+\typebuffer
+
+Of course these effects can also be achieved by combining (extra) grouping with
+\type {\aftergroup} calls, so this is more a convenience primitives than a real
+necessity: {\inlinebuffer}, as proven here.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {atendofgrouped}}]
+
+This is the multi token variant of \type {\atendofgroup}. Of course the next
+example is somewhat naive when it comes to spacing and so, but it shows the
+purpose.
+
+\startbuffer
+\bgroup
+\atendofgrouped{\bf QED}%
+\atendofgrouped{ (indeed)}%
+This sometimes looks nicer.
+\egroup
+\stopbuffer
+
+\typebuffer
+
+Multiple invocations are accumulated: {\inlinebuffer}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {toksapp}}]
+
+One way to append something to a token list is the following:
+
+\starttyping
+\scratchtoks\expandafter{\the\scratchtoks more stuff}
+\stoptyping
+
+This works all right, but it involves a copy of what is already in \type
+{\scratchtoks}. This is seldom a real issue unless we have large token lists and
+many appends. This is why \LUATEX\ introduced:
+
+\starttyping
+\toksapp\scratchtoks{more stuff}
+\toksapp\scratchtoksone\scratchtokstwo
+\stoptyping
+
+At some point, when working on \LUAMETATEX, I realized that primitives like this
+one and the next appenders and prependers to be discussed were always on the
+radar of Taco and me. Some were even implemented in what we called \type {eetex}:
+extended \ETEX, and we even found back the prototypes, dating from pre|-|\PDFTEX\
+times.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {etoksapp}}]
+
+A variant of \type {\toksapp} is the following: it expands the to be appended
+content.
+
+\starttyping
+\def\temp{more stuff}
+\etoksapp\scratchtoks{some \temp}
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {tokspre}}]
+
+Where appending something is easy because of the possible \type {\expandafter}
+trickery a prepend would involve more work, either using temporary token
+registers and|/|or using a mixture of the (no)expansion added by \ETEX, but all
+are kind of inefficient and cumbersome.
+
+\starttyping
+\tokspre\scratchtoks{less stuff}
+\tokspre\scratchtoksone\scratchtokstwo
+\stoptyping
+
+This prepends the token list that is provided.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {etokspre}}]
+
+A variant of \type {\tokspre} is the following: it expands the to be prepended
+content.
+
+\starttyping
+\def\temp{less stuff}
+\etokspre\scratchtoks{a bit \temp}
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {gtoksapp}}]
+
+This is the global variant of \type {\toksapp}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {xtoksapp}}]
+
+This is the global variant of \type {\etoksapp}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {gtokspre}}]
+
+This is the global variant of \type {\tokspre}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {xtokspre}}]
+
+This is the global variant of \type {\etokspre}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {csname}}]
+
+This original \TEX\ primitive starts the construction of a control sequence
+reference. It does a lookup and when no sequence with than name is found, it will
+create a hash entry and defaults its meaning to \type {\relax}.
+
+\starttyping
+\csname letters and other characters\endcsname
+\stoptyping
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {endcsname}}]
+
+This primitive is used in combination with \type {\csname}, \type {\ifcsname} and
+\type {\begincsname} where its end the scanning for the to be constructed control
+sequence token.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {begincsname}}]
+
+The next code creates a control sequence token from the given serialized tokens:
+
+\starttyping
+\csname mymacro\endcsname
+\stoptyping
+
+When \type {\mymacro} is not defined a control sequence will be created with the
+meaning \type {\relax}. A side effect is that a test for its existence might fail
+because it now exists. The next sequence will {\em not} create an controil
+sequence:
+
+\starttyping
+\begincsname mymacro\endcsname
+\stoptyping
+
+This actually is kind of equivalent to:
+
+\starttyping
+\ifcsname mymacro\endcsname
+ \csname mymacro\endcsname
+\fi
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {lastnamedcs}}]
+
+The example code in the previous section has some redundancy, in the sense that
+there to be looked up control sequence name \type {mymacro} is assembled twice.
+This is no big deal in a traditional eight bit \TEX\ but in a \UNICODE\ engine
+multi|-|byte sequences demand some more processing (although it is unlikely that
+control sequences have many multi|-|byte \UTF8\ characters).
+
+\starttyping
+\ifcsname mymacro\endcsname
+ \csname mymacro\endcsname
+\fi
+\stoptyping
+
+Instead we can say:
+
+\starttyping
+\ifcsname mymacro\endcsname
+ \lastnamedcs
+\fi
+\stoptyping
+
+Although there can be some performance benefits another advantage is that it uses
+less tokens and parsing. It might even look nicer.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {futureexpand}}]
+
+This primitive can be used as an alternative to a \type {\futurelet} approach,
+which is where the name comes from. \footnote {In the engine primitives
+that have similar behavior are grouped in commands that are then dealt with
+together, code wise.}
+
+\startbuffer
+\def\variantone<#1>{(#1)}
+\def\varianttwo#1{[#1]}
+\futureexpand<\variantone\varianttwo<one>
+\futureexpand<\variantone\varianttwo{two}
+\stopbuffer
+
+\typebuffer
+
+So, the next token determines which of the two variants is taken:
+
+{\getbuffer}
+
+Because we look ahead there is some magic involved: spaces are ignored but when
+we have no match they are pushed back into the input. The next variant
+demonstrates this:
+
+\startbuffer
+\def\variantone<#1>{(#1)}
+\def\varianttwo{}
+\def\temp{\futureexpand<\variantone\varianttwo}
+[\temp <one>]
+[\temp {two}]
+[\expandafter\temp\space <one>]
+[\expandafter\temp\space {two}]
+\stopbuffer
+
+\typebuffer
+
+This gives us:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {futureexpandis}}]
+
+We assume that the previous section is read. This variant will not push back
+spaces, which permits a consistent approach i.e.\ the user can assume that macro
+always gobbles the spaces.
+
+\startbuffer
+\def\variantone<#1>{(#1)}
+\def\varianttwo{}
+\def\temp{\futureexpandis<\variantone\varianttwo}
+[\temp <one>]
+[\temp {two}]
+[\expandafter\temp\space <one>]
+[\expandafter\temp\space {two}]
+\stopbuffer
+
+\typebuffer
+
+So, here no spaces are pushed back. This \type {is} in the name of this primitive
+means \quote {ignore spaces}, but having that added to the name would have made
+the primitive even more verbose (after all, we also don't have \type
+{\expandeddef} but \type {\edef} and no \type {\globalexpandeddef} but \type
+{\xdef}.
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {futureexpandisap}}]
+
+This primitive is like the one in the previous section but also ignores par
+tokens, so \type {isap} means \quote {ignore spaces and paragraphs}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {expandafter}}]
+
+This original \TEX\ primitive stores the next token, does a one level expansion
+of what follows it, which actually can be an not expandable token, and
+reinjects the stored token in the input. Like:
+
+\starttyping
+\expandafter\let\csname my weird macro name\endcsname{m w m n}
+\stoptyping
+
+Without \type {\expandafter} the \type {\csname} primitive would have been let to
+the left brace (effectively then a begin group). Actually in this particular case
+the control sequence with the weird name is injected and when it didn't yet exist
+it will get the meaning \type {\relax} so we sort of have two assignments in a
+row then.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {expandafterspaces}}]
+
+This is a gobbler: the next token is reinjected after following spaces have been
+read. Here is a simple example:
+
+\startbuffer
+[\expandafterspaces 1 2]
+[\expandafterspaces 3
+4]
+[\expandafterspaces 5
+
+6]
+\stopbuffer
+
+\typebuffer
+
+We get this typeset: \inlinebuffer, because a newline normally is configured to be
+a space (and leading spaces in a line are normally being ingored anyway).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {expandafterpars}}]
+
+Here is another gobbler: the next token is reinjected after following spaces
+and par tokens have been read. So:
+
+\startbuffer
+[\expandafterpars 1 2]
+[\expandafterpars 3
+4]
+[\expandafterpars 5
+
+6]
+\stopbuffer
+
+\typebuffer
+
+gives us: \inlinebuffer, because empty lines are like \type {\par} and therefore
+ignored.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {expandtoken}}]
+
+This primitive creates a token with a specific combination of catcode and
+character code. Because it assumes some knowledge of \TEX\ we can show it
+using some \type {\expandafter} magic:
+
+\startbuffer
+\expandafter\let\expandafter\temp\expandtoken 11 `X \meaning\temp\crlf
+\expandafter\let\expandafter\temp\expandtoken 12 `X \meaning\temp\crlf
+\stopbuffer
+
+\typebuffer
+
+The meanings are:
+
+{\getbuffer}
+
+Using other catcodes is possible but the results of injecting them into the input
+directly (or here by injecting \type {\temp}) can be unexpected because of what
+\TEX\ expects. You can get messages you normally won't get, for instance about
+unexpected alignment interference, which is a side effect of \TEX\ using some
+catcode|/|character combinations as signals and there is no reason to change
+those internals. That said:
+
+\startbuffer
+\edef\tempA{\expandtoken 9 `X} \meaning\tempA\crlf
+\edef\tempB{\expandtoken 10 `X} \meaning\tempB\crlf
+\edef\tempC{\expandtoken 11 `X} \meaning\tempC\crlf
+\edef\tempD{\expandtoken 12 `X} \meaning\tempD
+\stopbuffer
+
+\typebuffer
+
+are all valid and from the meaning you cannot really deduce what's in there:
+
+{\getbuffer}
+
+But you can be assured that:
+
+\startbuffer
+[AB: \ifx\tempA\tempB Y\else N\fi]
+[AC: \ifx\tempA\tempC Y\else N\fi]
+[AD: \ifx\tempA\tempD Y\else N\fi]
+[BC: \ifx\tempB\tempC Y\else N\fi]
+[BD: \ifx\tempB\tempD Y\else N\fi]
+[CD: \ifx\tempC\tempD Y\else N\fi]
+\stopbuffer
+
+\typebuffer
+
+makes clear that they're different: \inlinebuffer, and in case you wonder, the
+characters with catcode 10 are spaces, while those with code 9 are ignored.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {expandcstoken}}]
+
+The rationale behind this primitive is that when we \type {\let} a single token
+like a character it is hard to compare that with something similar, stored in a
+macro. This primitive pushes back a single token alias created by \type {\let}
+into the input.
+
+\startbuffer
+\let\tempA + \meaning\tempA \crlf
+\let\tempB X \meaning\tempB \crlf
+\let\tempC $ \meaning\tempC \par
+
+\edef\temp {\tempA} \doifelse{\temp}{+}{Y}{N} \meaning\temp \crlf
+\edef\temp {\tempB} \doifelse{\temp}{X}{Y}{N} \meaning\temp \crlf
+\edef\temp {\tempC} \doifelse{\temp}{X}{Y}{N} \meaning\temp \par
+
+\edef\temp{\expandcstoken\tempA} \doifelse{\temp}{+}{Y}{N} \meaning\temp \crlf
+\edef\temp{\expandcstoken\tempB} \doifelse{\temp}{X}{Y}{N} \meaning\temp \crlf
+\edef\temp{\expandcstoken\tempC} \doifelse{\temp}{$}{Y}{N} \meaning\temp \par
+
+\doifelse{\expandcstoken\tempA}{+}{Y}{N}
+\doifelse{\expandcstoken\tempB}{X}{Y}{N}
+\doifelse{\expandcstoken\tempC}{$}{Y}{N} \par
+\stopbuffer
+
+\typebuffer
+
+The meaning of the \type {\let} macros shows that we have a shortcut to a
+character with (in this case) catcode letter, other (here \quote {other
+character} gets abbreviated to \quote {character}), math shift etc.
+
+\start \tttf \getbuffer \stop
+
+Here we use the \CONTEXT\ macro \type {\doifelse} which can be implemented in
+different ways, but the only property relevant to the user is that the expanded
+content of the two arguments is compared.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {expand}}]
+
+Normally a protected macro will not be expanded inside for instance an \type
+{\edef} but there is a way out: \footnote {This primitive is dedicated to Hans vd
+Meer who was playing with the unprotected version of \type {\doifelse} and
+wondered about the reason for it not being expandable in the first place.}
+
+\startbuffer
+\edef\temp {\doifelse{a}{b}{c}{d}} \meaning\temp \crlf
+\edef\temp{\expand\doifelse{a}{b}{c}{d}} \meaning\temp
+\stopbuffer
+
+\typebuffer
+
+In the second case, the \type {\doifelse} command {\em is} expanded, but keep in mind
+that this only makes sense when the body of such a macro is expandable. This is the
+case in \CONTEXT\ \LMTX, but not in \MKIV.
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {ignorespaces}}]
+
+This traditional \TEX\ primitive signals the scanner to ignore the following
+spaces, if any. We mention it because we show a companion in the next section.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {ignorepars}}]
+
+This is a variant of \type {\ignorespaces}: following spaces {\em and} \type
+{\par} equivalent tokens are ignored, so for instance:
+
+\startbuffer
+one + \ignorepars
+
+two = \ignorepars \par
+three
+\stopbuffer
+
+\typebuffer
+
+renders as: \inlinebuffer. Traditionally \TEX\ has been sensitive to \type {\par}
+tokens in some of its building blocks. This has to do with the fact that it could
+indicate a runaway argument which in the times of slower machines and terminals
+was best to catch early. In \LUAMETATEX\ we no longer have long macros and the
+mechanisms that are sensitive can be told to accept \type {\par} tokens (and
+\CONTEXT\ set them such that this is the case).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ignorearguments}}]
+
+This primitive will quit argument scanning and start expansion of the body of a
+macro. The number of grabbed arguments can be tested as follows:
+
+\startbuffer
+\def\MyMacro[#1][#2][#3]%
+ {\ifarguments zero\or one\or two\or three \else hm\fi}
+
+\MyMacro \ignorearguments \quad
+\MyMacro [1]\ignorearguments \quad
+\MyMacro [1][2]\ignorearguments \quad
+\MyMacro [1][2][3]\ignorearguments \crlf
+\stopbuffer
+
+\typebuffer
+
+{\getbuffer}
+
+{\em Todo: explain optional delimiters.}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {lastarguments}}]
+
+\startbuffer
+\def\MyMacro #1{\the\lastarguments (#1) } \MyMacro{1} \crlf
+\def\MyMacro #1#2{\the\lastarguments (#1) (#2)} \MyMacro{1}{2} \crlf
+\def\MyMacro#1#2#3{\the\lastarguments (#1) (#2) (#3)} \MyMacro{1}{2}{3} \crlf
+
+\def\MyMacro #1{(#1) \the\lastarguments} \MyMacro{1} \crlf
+\def\MyMacro #1#2{(#1) (#2) \the\lastarguments} \MyMacro{1}{2} \crlf
+\def\MyMacro#1#2#3{(#1) (#2) (#3) \the\lastarguments} \MyMacro{1}{2}{3} \crlf
+\stopbuffer
+
+\typebuffer
+
+The value of \type {\lastarguments} can only be trusted in the expansion until
+another macro is seen and expanded. For instance in these examples, as soon as a
+character (like the left parenthesis) is seen, horizontal mode is entered and
+\type {\everypar} is expanded which in turn can involve macros. You can see that
+in the second block (that is: unless we changed \type {\everypar} in the
+meantime).
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {scantokens}}]
+
+Just forget about this \ETEX\ primnitive, just take the one in the next section.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {scantextokens}}]
+
+This primitive scans the input as if it comes from a file. In the next examples
+the \type {\detokenize} primitive turns tokenized code into verbatim code that is
+similar to what is read from a file.
+
+\startbuffer
+\edef\whatever{\detokenize{This is {\bf bold} and this is not.}}
+\detokenize {This is {\bf bold} and this is not.}\crlf
+\scantextokens{This is {\bf bold} and this is not.}\crlf
+\scantextokens{\whatever}\crlf
+\scantextokens\expandafter{\whatever}
+\stopbuffer
+
+\typebuffer
+
+This primitive does not have the end|-|of|-|file side effects of its precursor
+\type {\scantokens}.
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {number}}]
+
+This \TEX\ primitive serializes the next token into a number, assuming that it
+is indeed a number, like
+
+\starttyping
+\number`A
+\number65
+\number\scratchcounter
+\stoptyping
+
+For counters and such the \type {\the} primitive does the same, but when you're
+not sure if what follows is a verbose number or (for instance) a counter the
+\type {\number} primitive is a safer bet, because \type {\the 65} will not work.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {string}}]
+
+We mention this original primitive because of the one in the next section. It
+expands the next token or control sequence as if it was just entered, so normally
+a control sequence becomes a backslash followed by characters and a space.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {csstring}}]
+
+This primitive returns the name of the control sequence given without the leading
+escape character (normally a backslash). Of course you could strip that character
+with a simple helper but this is more natural.
+
+\startbuffer
+\csstring\mymacro
+\stopbuffer
+
+\typebuffer
+
+We get the name, not the meaning: {\tt \inlinebuffer}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {unexpanded}}]
+
+This is an \ETEX\ enhancement. The content will not be expanded in a context
+where expansion is happening, like in an \type {\edef}. In \CONTEXT\ you need to
+use \type {\normalunexpanded} because we already had a macro with that name.
+
+\startbuffer
+\def\A{!}
+\def\B{?}
+
+\edef\C{\A\B} \meaning\C \crlf
+\edef\C{\normalunexpanded{\A}\B} \meaning\C \crlf
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {detokenize}}]
+
+This \ETEX\ primitive turns the content of the provides list will become
+characters, kind of verbatim.
+
+\startbuffer
+\expandafter\let\expandafter\temp\detokenize{1} \meaning\temp \crlf
+\expandafter\let\expandafter\temp\detokenize{A} \meaning\temp \crlf
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {tokenized}}]
+
+Just as \type {\expanded} has a counterpart \type {\unexpanded}, it makes sense to give
+\type {\detokenize} a companion:
+
+\startbuffer
+\edef\foo{\detokenize{\inframed{foo}}}
+\edef\oof{\detokenize{\inframed{oof}}}
+
+\meaning\foo \crlf
+\dontleavehmode\foo
+
+\edef\foo{\tokenized{\foo\foo}}
+
+\meaning\foo \crlf
+\dontleavehmode\foo
+
+\dontleavehmode\tokenized{\foo\oof}
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+This primitive is similar to:
+
+\starttyping
+\def\tokenized#1{\scantextokens\expandafter{\normalexpanded{#1}}}
+\stoptyping
+
+and should be more efficient, not that it matters much as we don't use it that
+much (if at all).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {expanded}}]
+
+This primitive complements the two expansion related primitives mentioned in the
+previous two sections. This time the content will be expanded and then pushed
+back into the input. Protected macros will not be expanded, so you can use this
+primitive to expand the arguments in a call. In \CONTEXT\ you need to use \type
+{\normalexpanded} because we already had a macro with that name. We give some
+examples:
+
+\startbuffer
+\def\A{!}
+ \def\B#1{\string#1} \B{\A} \crlf
+ \def\B#1{\string#1} \normalexpanded{\noexpand\B{\A}} \crlf
+\protected\def\B#1{\string#1} \B{\A} \crlf
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {immediateassignment}}]
+
+Assignments are not expandable which means that you cannot define fully
+expandable macros that have assignments. But, there is a way out of this:
+
+\startbuffer
+\scratchcounter = 10
+\edef\whatever{%
+ (\the\scratchcounter)
+ \immediateassignment\scratchcounter\numexpr\scratchcounter+10\relax
+ \immediateassignment\advance\scratchcounter -5
+ (\the\scratchcounter)
+}
+\meaning\whatever
+\stopbuffer
+
+\typebuffer
+
+Don't expect miracles: you can't mix|-|in content or unexpandable tokens as they
+will either show up or quit the scanning.
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {immediateassigned}}]
+
+This is the multi|-|token variant of the primitive mentioned in the previous
+section.
+
+\startbuffer
+\scratchcounter = 10
+\edef\whatever{%
+ (\the\scratchcounter)
+ \immediateassigned{
+ \scratchcounter\numexpr\scratchcounter+10\relax
+ \advance\scratchcounter -5
+ }%
+ (\the\scratchcounter)
+}
+\meaning\whatever
+\stopbuffer
+
+\typebuffer
+
+The results are the same as in the previous section:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {if}}]
+
+This traditional \TEX\ conditional checks if two character codes are the same. In
+order to understand unexpanded results it is good to know that internally \TEX\
+groups primitives in a way that serves the implementation. Each primitive has a
+command code and a character code, but only for real characters the name
+character code makes sense. This condition only really tests for character codes
+when we have a character, in all other cases, the result is true.
+
+\startbuffer
+\def\A{A}\def\B{B} \chardef\C=`C \chardef\D=`D \def\AA{AA}
+
+[\if AA YES \else NOP \fi] [\if AB YES \else NOP \fi]
+[\if \A\B YES \else NOP \fi] [\if \A\A YES \else NOP \fi]
+[\if \C\D YES \else NOP \fi] [\if \C\C YES \else NOP \fi]
+[\if \count\dimen YES \else NOP \fi] [\if \AA\A YES \else NOP \fi]
+
+\stopbuffer
+
+\typebuffer
+
+The last example demonstrates that the tokens get expanded, which is why
+we get the extra \type {A}:
+
+{\getbuffer}
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifcat}}]
+
+Another traditional \TEX\ primitive: what happens with what gets read in depends
+on the catcode of a character, think of characters marked to start math mode, or
+alphabetic characters (letters) versus other characters (like punctuation).
+
+\startbuffer
+\def\A{A}\def\B{,} \chardef\C=`C \chardef\D=`, \def\AA{AA}
+
+[\ifcat $! YES \else NOP \fi] [\ifcat () YES \else NOP \fi]
+[\ifcat AA YES \else NOP \fi] [\ifcat AB YES \else NOP \fi]
+[\ifcat \A\B YES \else NOP \fi] [\ifcat \A\A YES \else NOP \fi]
+[\ifcat \C\D YES \else NOP \fi] [\ifcat \C\C YES \else NOP \fi]
+[\ifcat \count\dimen YES \else NOP \fi] [\ifcat \AA\A YES \else NOP \fi]
+\stopbuffer
+
+\typebuffer
+
+Close reading is needed here:
+
+{\getbuffer}
+
+This traditional \TEX\ condition as a well as the one in the previous section are
+hardly used in \CONTEXT, if only because they expand what follows and we seldom
+need to compare characters.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifnum}}]
+
+This is a frequently used conditional: it compares two numbers where a number is
+anything that can be seen as such.
+
+\startbuffer
+\scratchcounter=65 \chardef\A=65
+
+\ifnum65=`A YES \else NOP\fi
+\ifnum\scratchcounter=65 YES \else NOP\fi
+\ifnum\scratchcounter=\A YES \else NOP\fi
+\stopbuffer
+
+\typebuffer
+
+Unless a number is an unexpandable token it ends with a space or \type {\relax},
+so when you end up in the true branch, you'd better check if \TEX\ could
+determine where the number ends.
+
+{\getbuffer}
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifdim}}]
+
+Dimensions can be compared with this traditional \TEX\ primitive.
+
+\startbuffer
+\scratchdimen=1pt \scratchcounter=65536
+
+\ifdim\scratchdimen=\scratchcounter sp YES \else NOP\fi
+\ifdim\scratchdimen=1 pt YES \else NOP\fi
+\stopbuffer
+
+\typebuffer
+
+The units are mandate:
+
+{\getbuffer}
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifodd}}]
+
+One reason for this condition to be around is that in a double sided layout we
+need test for being on an odd or even page. It scans for a number the same was
+as other primitives,
+
+\startbuffer
+\ifodd65 YES \else NO\fi &
+\ifodd`B YES \else NO\fi .
+\stopbuffer
+
+\typebuffer
+
+So: {\inlinebuffer}
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifvmode}}]
+
+This traditional conditional checks we are in (internal) vertical mode.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifhmode}}]
+
+This traditional conditional checks we are in (restricted) horizontal mode.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifmmode}}]
+
+This traditional conditional checks we are in (inline or display) math mode mode.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifinner}}]
+
+This traditional one can be confusing. It is true when we are in restricted
+horizontal mode (a box), internal vertical mode (a box), or inline math mode.
+
+\startbuffer
+test \ifhmode \ifinner INNER\fi HMODE\fi\crlf
+\hbox{test \ifhmode \ifinner INNER \fi HMODE\fi} \crlf
+
+\ifvmode \ifinner INNER\fi VMODE \fi\crlf
+\vbox{\ifvmode \ifinner INNER \fi VMODE\fi} \crlf
+\vbox{\ifinner INNER \ifvmode VMODE \fi \fi} \crlf
+\stopbuffer
+
+\typebuffer
+
+Watch the last line: because we typeset \type {INNER} we enter horizontal mode:
+
+{\getbuffer}
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifvoid}}]
+
+This traditional conditional checks if a given box register or internal box
+variable has any content.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifhbox}}]
+
+This traditional conditional checks if a given box register or internal box
+variable represents a horizontal box,
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifvbox}}]
+
+This traditional conditional checks if a given box register or internal box
+variable represents a vertical box,
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifx}}]
+
+We use this traditional \TEX\ conditional a lot in \CONTEXT. Contrary to \type {\if}
+the two tokens that are compared are not expanded. This makes it possible to compare
+the meaning of two macros. Depending on the need, these macros can have their content
+expanded or not. A different number of parameters results in false.
+
+Control sequences are identical when they have the same command code and
+character code. Because a \type {\let} macro is just a reference, both let macros
+are the same and equal to \type {\relax}:
+
+\starttyping
+\let\one\relax \let\two\relax
+\stoptyping
+
+The same is true for other definitions that result in the same (primitive) or
+meaning encoded in the character field (think of \type {\chardef}s and so).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifeof}}]
+
+This traditional conditional checks if current pointer into the the file bound to
+the given index is past the end of file. The read and write channels are not
+really used in \CONTEXT: in \MKII\ we only had one file for all multi|-|pass
+data, and in \MKIV\ all file related stuff is dealt with in \LUATEX.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {iftrue}}]
+
+Here we have a traditional \TEX\ conditional that is always true (therefore the
+same is true for any macro that is \type {\let} to this primitive).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {iffalse}}]
+
+Here we have a traditional \TEX\ conditional that is always false (therefore the
+same is true for any macro that is \type {\let} to this primitive).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifcase}}]
+
+This numeric \TEX\ conditional takes a counter (literal, register, shortcut to a
+character, internal quantity) and goes to the branch that matches.
+
+\startbuffer
+\ifcase 3 zero\or one\or two\or three\or four\else five or more\fi
+\stopbuffer
+
+\typebuffer
+
+Indeed: \inlinebuffer\ equals three. In later sections we will see some
+\LUAMETATEX\ primitives that behave like an \type {\ifcase}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifdefined}}]
+
+In traditional \TEX\ checking for a macro to exist was a bit tricky and therefore
+\ETEX\ introduced a convenient conditional. We can do this:
+
+\starttyping
+\ifx\MyMacro\undefined ... \else ... \fi
+\stoptyping
+
+but that assumes that \type {\undefined} is indeed undefined. Another test often
+seen was this:
+
+\starttyping
+\expandafter\ifx\csname MyMacro\endcsname\relax ... \else ... \fi
+\stoptyping
+
+Instead of comparing with \type {\undefined} we need to check with \type {\relax}
+because the control sequence is defined when not yet present and defaults to
+\type {\relax}. This is not pretty.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {ifcsname}}]
+
+This is an \ETEX\ conditional that complements the one on the previous section:
+
+\starttyping
+\expandafter\ifx\csname MyMacro\endcsname\relax ... \else ... \fi
+ \ifcsname MyMacro\endcsname ... \else ... \fi
+\stoptyping
+
+Here the first one has the side effect of defining the macro and defaulting it to
+\type {\relax}, while the second one doesn't do that. Juts think of checking a
+few million different names: the first one will deplete the hash table and
+probably string space too.
+
+In \LUAMETATEX\ the construction stops when there is no letter or other character
+seen (\TEX\ expands on the go so expandable macros are dealt with). Instead of an
+error message, the match is simply false and all tokens till the \type
+{\endcsname} are gobbled.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {iffontchar}}]
+
+This is an \ETEX\ conditional. It takes a font identifier and a character number.
+In modern fonts simply checking could not be enough because complex font features
+can swap in other ones and their index can be anything. Also, a font mechanism
+can provide fallback fonts and characters, so don't rely on this one too much. It
+just reports true when the font passed to the frontend has a slot filled.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {ifincsname}}]
+
+This conditional is sort of obsolete and can be used to check if we're inside a
+\type {\csname} or \type {\ifcsname} construction. It's not used in \CONTEXT.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifabsnum}}]
+
+This test will negate negative numbers before comparison, as in:
+
+\startbuffer
+\def\TestA#1{\ifnum #1<100 too small\orelse\ifnum #1>200 too large\else okay\fi}
+\def\TestB#1{\ifabsnum#1<100 too small\orelse\ifabsnum#1>200 too large\else okay\fi}
+
+\TestA {10}\quad\TestA {150}\quad\TestA {210}\crlf
+\TestB {10}\quad\TestB {150}\quad\TestB {210}\crlf
+\TestB{-10}\quad\TestB{-150}\quad\TestB{-210}\crlf
+\stopbuffer
+
+\typebuffer
+
+Here we get the same result each time:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifabsdim}}]
+
+This test will negate negative dimensions before comparison, as in:
+
+\startbuffer
+\def\TestA#1{\ifdim #1<2pt too small\orelse\ifdim #1>4pt too large\else okay\fi}
+\def\TestB#1{\ifabsdim#1<2pt too small\orelse\ifabsdim#1>4pt too large\else okay\fi}
+
+\TestA {1pt}\quad\TestA {3pt}\quad\TestA {5pt}\crlf
+\TestB {1pt}\quad\TestB {3pt}\quad\TestB {5pt}\crlf
+\TestB{-1pt}\quad\TestB{-3pt}\quad\TestB{-5pt}\crlf
+\stopbuffer
+
+\typebuffer
+
+So we get this:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifchknum}}]
+
+In \CONTEXT\ there are quite some cases where a variable can have a number or a
+keyword indicating a symbolic name of a number or maybe even some special
+treatment. Checking if a valid number is given is possible to some extend, but a
+native checker makes much sense too. So here is one:
+
+\startbuffer
+\ifchknum oeps\or okay\else error\fi\quad
+\ifchknum 12 \or okay\else error\fi\quad
+\ifchknum 12pt\or okay\else error\fi
+\stopbuffer
+
+\typebuffer
+
+The result is as expected:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifchkdim}}]
+
+A variant on the checker in the previous section is a dimension checker:
+
+\startbuffer
+\ifchkdim oeps\or okay\else error\fi\quad
+\ifchkdim 12 \or okay\else error\fi\quad
+\ifchkdim 12pt\or okay\else error\fi
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifcmpnum}}]
+
+This conditional compares two numbers and the resulting \type {\ifcase} reflects
+their relation:
+
+\startbuffer
+[1 2 : \ifcmpnum 1 2 less\or equal\or more\fi]\quad
+[1 1 : \ifcmpnum 1 1 less\or equal\or more\fi]\quad
+[2 1 : \ifcmpnum 2 1 less\or equal\or more\fi]
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifcmpdim}}]
+
+This conditional compares two dimensions and the resulting \type {\ifcase}
+reflects their relation:
+
+\startbuffer
+[1pt 2pt : \ifcmpdim 1pt 2pt less\or equal\or more\fi]\quad
+[1pt 1pt : \ifcmpdim 1pt 1pt less\or equal\or more\fi]\quad
+[2pt 1pt : \ifcmpdim 2pt 1pt less\or equal\or more\fi]
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifnumval}}]
+
+This conditional is a variant on \type {\ifchknum}. This time we get
+some more detail about the value:
+
+\startbuffer
+[-12 : \ifnumval -12\or negative\or zero\or positive\else error\fi]\quad
+[0 : \ifnumval 0\or negative\or zero\or positive\else error\fi]\quad
+[12 : \ifnumval 12\or negative\or zero\or positive\else error\fi]\quad
+[oeps : \ifnumval oeps\or negative\or zero\or positive\else error\fi]
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifdimval}}]
+
+This conditional is a variant on \type {\ifchkdim} and provides some more
+detailed information about the value:
+
+\startbuffer
+[-12pt : \ifdimval-12pt\or negative\or zero\or positive\else error\fi]\quad
+[0pt : \ifdimval 0pt\or negative\or zero\or positive\else error\fi]\quad
+[12pt : \ifdimval 12pt\or negative\or zero\or positive\else error\fi]\quad
+[oeps : \ifdimval oeps\or negative\or zero\or positive\else error\fi]
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {iftok}}]
+
+When you want to compare two arguments, the usual way to do this is the
+following:
+
+\starttyping
+\edef\tempA{#1}
+\edef\tempb{#2}
+\ifx\tempA\tempB
+ the same
+\else
+ different
+\fi
+\stoptyping
+
+This works quite well but the fact that we need to define two macros can be
+considered a bit of a nuisance. It also makes macros that use this method to be
+not so called \quote {fully expandable}. The next one avoids both issues:
+
+\starttyping
+\iftok{#1}{#2}
+ the same
+\else
+ different
+\fi
+\stoptyping
+
+Instead of direct list you can also pass registers, so given:
+
+\startbuffer[a]
+\scratchtoks{a}%
+\toks0{a}%
+\stopbuffer
+
+\typebuffer[a]
+
+This:
+
+\startbuffer[b]
+\iftok 0 \scratchtoks Y\else N\fi\space
+\iftok{a}\scratchtoks Y\else N\fi\space
+\iftok\scratchtoks\scratchtoks Y\else N\fi
+\stopbuffer
+
+\typebuffer[b]
+
+{\getbuffer[a]gives: \inlinebuffer[b].}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifcstok}}]
+
+A variant on the primitive mentioned in the previous section is one that
+operates on lists and macros:
+
+\startbuffer[a]
+\def\a{a} \def\b{b} \def\c{a}
+\stopbuffer
+
+\typebuffer[a]
+
+\startbuffer[b]
+\ifcstok\a\b Y\else N\fi\space
+\ifcstok\a\c Y\else N\fi\space
+\ifcstok{\a}\c Y\else N\fi\space
+\ifcstok{a}\c Y\else N\fi
+\stopbuffer
+
+This:
+
+\typebuffer[b]
+
+{\getbuffer[a]will give us: \inlinebuffer[b].}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifcondition}}]
+
+The conditionals in \TEX\ are hard coded as primitives and although it might
+look like \type {\newif} creates one, it actually just defined three macros.
+
+\startbuffer
+\newif\ifMyTest
+\meaning\MyTesttrue \crlf
+\meaning\MyTestfalse \crlf
+\meaning\ifMyTest \crlf \MyTesttrue
+\meaning\ifMyTest \crlf
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+This means that when you say:
+
+\starttyping
+\ifMytest ... \else ... \fi
+\stoptyping
+
+You actually have one of:
+
+\starttyping
+\iftrue ... \else ... \fi
+\iffalse ... \else ... \fi
+\stoptyping
+
+and because these are proper conditions nesting them like:
+
+\starttyping
+\ifnum\scratchcounter > 0 \ifMyTest A\else B\fi \fi
+\stoptyping
+
+will work out well too. This is not true for macros, so for instance:
+
+\starttyping
+\scratchcounter = 1
+\unexpanded\def\ifMyTest{\iftrue}
+\ifnum\scratchcounter > 0 \ifMyTest A\else B\fi \fi
+\stoptyping
+
+will make a run fail with an error (or simply loop forever, depending on your
+code). This is where \type {\ifcondition} enters the picture:
+
+\starttyping
+\def\MyTest{\iftrue} \scratchcounter0
+\ifnum\scratchcounter > 0
+ \ifcondition\MyTest A\else B\fi
+\else
+ x
+\fi
+\stoptyping
+
+This primitive is seen as a proper condition when \TEX\ is in \quotation {fast
+skipping unused branches} mode but when it is expanding a branch, it checks if
+the next expanded token is a proper tests and if so, it deals with that test,
+otherwise it fails. The main condition here is that the \type {\MyTest} macro
+expands to a proper true or false test, so, a definition like:
+
+\starttyping
+\def\MyTest{\ifnum\scratchcounter<10 }
+\stoptyping
+
+is also okay. Now, is that neat or not?
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {iffrozen}}]
+
+This conditional checks if a control sequence is frozen:
+
+\starttyping
+is \iffrozen\MyMacro \else not \fi frozen
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifprotected}}]
+
+This conditional checks if a control sequence is protected:
+
+\starttyping
+is \ifprotected\MyMacro \else not \fi protected
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifusercmd}}]
+
+This conditional checks if a control sequence is not one of the primitives:
+
+\starttyping
+is \ifusercmd\MyMacro \else not \fi a primitive
+\stoptyping
+
+It is not always possible to determine this but it should work okay for regular
+macros, register allocations and character definitions.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifempty}}]
+
+This conditional checks if a control sequence is empty:
+
+\starttyping
+is \ifempty\MyMacro \else not \fi empty
+\stoptyping
+
+It is basically a shortcut of:
+
+\starttyping
+is \ifx\MyMacro\empty \else not \fi empty
+\stoptyping
+
+with:
+
+\starttyping
+\def\empty{}
+\stoptyping
+
+Of course this is not empty at all:
+
+\starttyping
+\def\notempty#1{}
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifboolean}}]
+
+This tests a number (register or equivalent) and any nonzero value represents
+\type {true}, which is nicer than using an \type {\unless \ifcase}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifmathparameter}}]
+
+This is an \type {\ifcase} where the value depends on if the given math parameter
+is zero, (\type {0}), set (\type {1}), or unset (\type {2}).
+
+\starttyping
+\ifmathparameter\Umathpunctclosespacing\displaystyle
+ zero \or
+ nonzero \or
+ unset \fi
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifmathstyle}}]
+
+This is a variant of \type {\ifcase} were the number is one of the seven possible
+styles: display, text, cramped text, script, cramped script, script script,
+cramped script script.
+
+\starttyping
+\ifmathstyle
+ display
+\or
+ text
+\or
+ cramped text
+\else
+ normally smaller than text
+\fi
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifarguments}}]
+
+This is a variant of \type {\ifcase} were the selector is the number of arguments
+picked up. For example:
+
+\startbuffer
+\def\MyMacro#1#2#3{\ifarguments\0\or1\or2\or3\else ?\fi} \MyMacro{A}{B}{C}
+\def\MyMacro#1#0#3{\ifarguments\0\or1\or2\or3\else ?\fi} \MyMacro{A}{B}{C}
+\def\MyMacro#1#-#2{\ifarguments\0\or1\or2\or3\else ?\fi} \MyMacro{A}{B}{C}\crlf
+\stopbuffer
+
+\typebuffer
+
+Watch the non counted, ignored, argument in the last case. Normally this test will
+be used in combination with \type {\ignorearguments}.
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifhastok}}]
+
+This conditional looks for occurrences in token lists where each argument has to
+be a proper list.
+
+\startbuffer
+\def\scratchtoks{x}
+
+\ifhastoks{yz} {xyz} Y\else N\fi\quad
+\ifhastoks\scratchtoks {xyz} Y\else N\fi
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifhastoks}}]
+
+This test compares two token lists. When a macro is passed it's meaning
+gets used.
+
+\startbuffer
+\def\x {x}
+\def\xyz{xyz}
+
+(\ifhastoks {x} {xyz}Y\else N\fi)\quad
+(\ifhastoks {\x} {xyz}Y\else N\fi)\quad
+(\ifhastoks \x {xyz}Y\else N\fi)\quad
+(\ifhastoks {y} {xyz}Y\else N\fi)\quad
+(\ifhastoks {yz} {xyz}Y\else N\fi)\quad
+(\ifhastoks {yz} {\xyz}Y\else N\fi)
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {ifhasxtoks}}]
+
+This primitive is like the one in the previous section but this time the
+given lists are expanded.
+
+\startbuffer
+\def\x {x}
+\def\xyz{\x yz}
+
+(\ifhasxtoks {x} {xyz}Y\else N\fi)\quad
+(\ifhasxtoks {\x} {xyz}Y\else N\fi)\quad
+(\ifhastoks \x {xyz}Y\else N\fi)\quad
+(\ifhasxtoks {y} {xyz}Y\else N\fi)\quad
+(\ifhasxtoks {yz} {xyz}Y\else N\fi)\quad
+(\ifhasxtoks {yz} {\xyz}Y\else N\fi)
+\stopbuffer
+
+\typebuffer {\getbuffer}
+
+This primitive has some special properties.
+
+\startbuffer
+\edef\+{\expandtoken 9 `+}
+
+\ifhasxtoks {xy} {xyz}Y\else N\fi\quad
+\ifhasxtoks {x\+y} {xyz}Y\else N\fi
+\stopbuffer
+
+\typebuffer
+
+Here the first argument has a token that has category code \quote {ignore} which
+means that such a character will be skipped when seen. So the result is:
+
+{\getbuffer}
+
+This permits checks like these:
+
+\startbuffer
+\edef\,{\expandtoken 9 `,}
+
+\ifhasxtoks{\,x\,} {,x,y,z,}Y\else N\fi\quad
+\ifhasxtoks{\,y\,} {,x,y,z,}Y\else N\fi\quad
+\ifhasxtoks{\,z\,} {,x,y,z,}Y\else N\fi\quad
+\ifhasxtoks{\,x\,} {,xy,z,}Y\else N\fi
+\stopbuffer
+
+\typebuffer
+
+I admit that it needs a bit of a twisted mind to come up with this, but it works
+ok:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {else}}]
+
+This traditional primitive is part of the condition testing mechanism. When a
+condition matches, \TEX\ will continue till it sees an \type {\else} or \type
+{\or} or \type {\orelse} (to be discussed later). It will then do a fast skipping
+pass till it sees an \type {\fi}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {or}}]
+
+This traditional primitive is part of the condition testing mechanism and relates
+to an \type {\ifcase} test (or a similar test to be introduced in later
+sections). Depending on the value, \TEX\ will do a fast scanning till the right
+\type {\or} is seen, then it will continue expanding till it sees a \type {\or}
+or \type {\else} or \type {\orelse} (to be discussed later). It will then do a
+fast skipping pass till it sees an \type {\fi}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {fi}}]
+
+This traditional primitive is part of the condition testing mechanism and ends a
+test. So, we have:
+
+\starttyping
+\ifsomething ... \else ... \fi
+\ifsomething ... \or ... \or ... \else ... \fi
+\ifsomething ... \orelse \ifsometing ... \else ... \fi
+\ifsomething ... \or ... \orelse \ifsometing ... \else ... \fi
+\stoptyping
+
+The \type {\orelse} is new in \LUAMETATEX\ and a continuation like we find in
+other programming languages (see later section).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {unless}}]
+
+This \ETEX\ prefix will negate the test (when applicable).
+
+\starttyping
+ \ifx\one\two YES\else NO\fi
+\unless\ifx\one\two NO\else YES\fi
+\stoptyping
+
+This primitive is hardly used in \CONTEXT\ and we probably could get rid of these
+few cases.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {orelse}}]
+
+This primitive provides a convenient way to flatten your conditional tests. So
+instead of
+
+\starttyping
+\ifnum\scratchcounter<-10
+ too small
+\else\ifnum\scratchcounter>10
+ too large
+\else
+ just right
+\fi\fi
+\stoptyping
+
+You can say this:
+
+\starttyping
+\ifnum\scratchcounter<-10
+ too small
+\orelse\ifnum\scratchcounter>10
+ too large
+\else
+ just right
+\fi
+\stoptyping
+
+You can mix tests and even the case variants will work in most cases \footnote {I
+just play safe because there are corner cases that might not work yet.}
+
+\starttyping
+\ifcase\scratchcounter zero
+\or one
+\or two
+\orelse\ifnum\scratchcounter<10 less than ten
+\else ten or more
+\fi
+\stoptyping
+
+Performance wise there are no real benefits although in principle there is a bit
+less housekeeping involved than with nested checks. However you might like this:
+
+\starttyping
+\ifnum\scratchcounter<-10
+ \expandafter\toosmall
+\orelse\ifnum\scratchcounter>10
+ \expandafter\toolarge
+\else
+ \expandafter\justright
+\fi
+\stoptyping
+
+over:
+
+\starttyping
+\ifnum\scratchcounter<-10
+ \expandafter\toosmall
+\else\ifnum\scratchcounter>10
+ \expandafter\expandafter\expandafter\toolarge
+\else
+ \expandafter\expandafter\expandafter\justright
+\fi\fi
+\stoptyping
+
+or the more \CONTEXT\ specific:
+
+\starttyping
+\ifnum\scratchcounter<-10
+ \expandafter\toosmall
+\else\ifnum\scratchcounter>10
+ \doubleexpandafter\toolarge
+\else
+ \doubleexpandafter\justright
+\fi\fi
+\stoptyping
+
+But then, some \TEX ies like complex and obscure code and throwing away working
+old code that took ages to perfect and get working and also showed that one
+masters \TEX\ might hurt.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {futurelet}}]
+
+The original \TEX\ primitive \type {\futurelet} can be used to create an alias to a next token,
+push it back into the input and then expand a given token.
+
+\startbuffer
+\let\MySpecialToken[
+\def\DoWhatever{\ifx\NextToken\MySpecialToken YES\else NOP\fi : }
+\futurelet\NextToken\DoWhatever [A]\crlf
+\futurelet\NextToken\DoWhatever (A)
+\stopbuffer
+
+\typebuffer
+
+This is typically the kind of primitive that most users will never use because it
+expects a sane follow up handler (here \type {\DoWhatever}) and therefore is
+related to user interfacing.
+
+{\getbuffer}
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {futuredef}}]
+
+We elaborate on the example of using \type {\futurelet} in the previous section.
+Compare that one with the next:
+
+\startbuffer
+\def\MySpecialToken{[}
+\def\DoWhatever{\ifx\NextToken\MySpecialToken YES\else NOP\fi : }
+\futurelet\NextToken\DoWhatever [A]\crlf
+\futurelet\NextToken\DoWhatever (A)
+\stopbuffer
+
+\typebuffer
+
+This time we get:
+
+{\getbuffer}
+
+It is for that reason that we now also have \type {\futuredef}:
+
+\startbuffer
+\def\MySpecialToken{[}
+\def\DoWhatever{\ifx\NextToken\MySpecialToken YES\else NOP\fi : }
+\futuredef\NextToken\DoWhatever [A]\crlf
+\futuredef\NextToken\DoWhatever (A)
+\stopbuffer
+
+\typebuffer
+
+So we're back to what we want:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {letcharcode}}]
+
+Assigning a meaning to an active character can sometimes be a bit cumbersome;
+think of using some documented uppercase magic that one tends to forget as it's
+used only a few times and then never looked at again. So we have this:
+
+\startbuffer
+{\letcharcode 65 1 \catcode 65 13 A : \meaning A}\crlf
+{\letcharcode 65 2 \catcode 65 13 A : \meaning A}\crlf
+\stopbuffer
+
+\typebuffer
+
+here we define \type {A} as an active charcter with meaning \type {1} in the
+first line and \type {2} in the second.
+
+{\getbuffer}
+
+Normally one will assign a control sequence:
+
+\startbuffer
+{\letcharcode 66 \bf \catcode 66 13 {B bold}: \meaning B}\crlf
+{\letcharcode 73 \it \catcode 73 13 {I italic}: \meaning I}\crlf
+\stopbuffer
+
+\typebuffer
+
+Of course \type {\bf} and \type {\it} are \CONTEXT\ specific commands:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startoldprimitive[title={\tex {global}}]
+
+This is one of the original prefixes that can be used when we define a macro of
+change some register.
+
+\starttyping
+\bgroup
+ \def\MyMacroA{a}
+\global\def\MyMacroB{a}
+ \gdef\MyMacroC{a}
+\egroup
+\stoptyping
+
+The macro defined in the first line is forgotten when the groups is left. The
+second and third definition are both global and these definitions are retained.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {long}}]
+
+This original prefix gave the macro being defined the property that it could not
+have \type {\par} (or the often equivalent empty lines) in its arguments. It was
+mostly a protection against a forgotten right curly brace, resulting in a so called
+run|-|away argument. That mattered on a paper terminal or slow system where such a
+situation should be catched early. In \LUATEX\ it was already optional, and in
+\LUAMETATEX\ we dropped this feature completely (so that we could introduce others).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {outer}}]
+
+An outer macro is one that can only be used at the outer level. This property is
+no longer supported. Like \type {\long}, the \type {\outer} prefix is now an
+no|-|op (and we don't expect this to have unfortunate side effects).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\tex {protected}}]
+
+A protected macro is one that doesn't get expanded unless it is time to do so.
+For instance, inside an \type {\edef} it just stays what it is. It often makes
+sense to pass macros as|-|is to (multi|-|pass) file (for tables of contents).
+
+In \CONTEXT\ we use either \type {\protected} or \type {\unexpanded} because the
+later was the command we used to achieve the same results before \ETEX\
+introduced this protection primitive. Originally the \type {\protected} macro was
+also defined but it has been dropped.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\tex {frozen}}]
+
+You can define a macro as being frozen:
+
+\starttyping
+\frozen\def\MyMacro{...}
+\stoptyping
+
+When you redefine this macro you get an error:
+
+\starttyping
+! You can't redefine a frozen macro.
+\stoptyping
+
+This is a prefix like \type {\global} and it can be combined with other prefixes.
+\footnote {The \type {\outer} and \type {\long} prefixes are no|-|ops in
+\LUAMETATEX\ and \LUATEX\ can be configured to ignore them.}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {letfrozen}}]
+
+You can explicitly freeze an unfrozen macro:
+
+\starttyping
+\def\MyMacro{...}
+\letfrozen\MyMacro
+\stoptyping
+
+A redefinition will now give:
+
+\starttyping
+! You can't redefine a frozen macro.
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {unletfrozen}}]
+
+A frozen macro cannot be redefined: you get an error. But as nothing in \TEX\ is set
+in stone, you can do this:
+
+\starttyping
+\frozen\def\MyMacro{...}
+\unletfrozen\MyMacro
+\stoptyping
+
+and \type {\MyMacro} is no longer protected from overloading. It is still
+undecided to what extend \CONTEXT\ will use this feature.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {letprotected}}]
+
+Say that you have these definitions:
+
+\startbuffer
+ \def \MyMacroA{alpha}
+\protected \def \MyMacroB{beta}
+ \edef \MyMacroC{\MyMacroA\MyMacroB}
+\letprotected \MyMacroA
+ \edef \MyMacroD{\MyMacroA\MyMacroB}
+\meaning \MyMacroC\crlf
+\meaning \MyMacroD
+\stopbuffer
+
+\typebuffer
+
+The typeset meaning in this example is:
+
+{\tttf \getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {unletprotected}}]
+
+The complementary operation of \type {\letprotected} can be used to unprotect
+a macro, so that it gets expandable.
+
+\startbuffer
+ \def \MyMacroA{alpha}
+\protected \def \MyMacroB{beta}
+ \edef \MyMacroC{\MyMacroA\MyMacroB}
+\unletprotected \MyMacroB
+ \edef \MyMacroD{\MyMacroA\MyMacroB}
+\meaning \MyMacroC\crlf
+\meaning \MyMacroD
+\stopbuffer
+
+\typebuffer
+
+Compare this with the example in the previous section:
+
+{\tttf \getbuffer}
+
+\stopnewprimitive
+
+% \startnewprimitive[title={\tex {letdatacode}}]
+% {\em Todo.}
+% \stopnewprimitive
+
+\startnewprimitive[title={\tex {beginlocalcontrol}}]
+
+Once \TEX\ is initialized it will enter the main loop. In there certain commands
+trigger a function that itself can trigger further scanning and functions. In
+\LUAMETATEX\ we can have local main loops and we can either enter it from the
+\LUA\ end (which we don't discuss here) or at the \TEX\ end using this primitive.
+
+\startbuffer
+\scratchcounter100
+
+\edef\whatever{
+ a
+ \beginlocalcontrol
+ \advance\scratchcounter 10
+ b
+ \endlocalcontrol
+ \beginlocalcontrol
+ c
+ \endlocalcontrol
+ d
+ \advance\scratchcounter 10
+}
+
+\the\scratchcounter
+\whatever
+\the\scratchcounter
+\stopbuffer
+
+\typebuffer
+
+A bit of close reading probably gives an impression of what happens here:
+
+{\getbuffer}
+
+The local loop can actually result in material being injected in the current node
+list. However, where normally assignments are not taking place in an \type
+{\edef}, here they are applied just fine. Basically we have a local \TEX\ job, be
+it that it shares all variables with the parent loop.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {endlocalcontrol}}]
+
+ See previous section.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {alignmark}}]
+
+When you have the \type{#} not set up as macro parameter character cq.\ align
+mark, you can use this primitive instead. The same rules apply with respect to
+multiple such tokens in (nested) macros and alignments.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\tex {aligntab}}]
+
+When you have the \type{&} not set up as align tab, you can use this primitive
+instead. The same rules apply with respect to multiple such tokens in (nested)
+macros and alignments.
+
+\stopnewprimitive
+
+\page
+
+% % It doesn't make sense to typeset this, also because it makes me feel old.
+%
+% \startsubject[title=A few notes on extensions] % ,placeholder=todo]
+%
+% This is a companion to the regular \LUAMETATEX\ reference manual, which is mostly
+% a concise summary of the program and its features. They don't replace each other,
+% and none of them claims completeness. There might be more manuals that discuss
+% specific kind of extensions in the future. First some comments on extensions.
+%
+% The starting point of all \TEX\ engines is \TEX. The first follow up was \TEX\
+% with support for 8 bit and languages. After that it took some time, but then two
+% projects started that extended \TEX: \ETEX\ and \OMEGA. In the end the first
+% brought some extensions to the macro machinery, more registers, a simple right to
+% left typesetting feature, some more tracing, etc. The second was more ambitious
+% and has input translation mechanisms, larger fonts, and multi directional
+% typesetting. By the time \ETEX\ became stable, the \PDFTEX\ engine had showed up
+% and at some point it integrated \ETEX. But \PDFTEX\ itself also extended the
+% several components that make up \TEX. The \NTS\ project was started as follow up
+% on \ETEX\ but although an engine written in \JAVA\ was the result it never was
+% used for extensions; this project was fully funded by the german language user
+% group.
+%
+% The \CONTEXT\ macro package was an early adopter of the \ETEX\ and \PDFTEX\
+% extensions. Probably the most significant effect was that we got more registers
+% (some other features were already kind of present in macro form). In between
+% these engines we played with \type {eetex} (extended \ETEX) because we had some
+% wishes of our own. We also explored extensions to the \DVI\ format but in the end
+% \PDF\ won that race. An example of a new mechanism that we introduced in
+% \CONTEXT\ was position tracking: marking positions that can be saved when the
+% output is created and used in a second run. This started as a \DVI\ postprocessor
+% in \PERL\ written by me, later turned into a \CLANGUAGE\ program by Taco, and
+% eventually integrated in \PDFTEX\ by Thanh (\PDFTEX\ was a phd project). At some
+% point \XETEX\ was developed, funded and driven by an organization that did high
+% end multi lingual typesetting; it was based on \ETEX\ and uses a \DVI\ to \PDF\
+% backend processor. Both \PDFTEX\ and \XETEX\ are supported by \CONTEXT\ \MKII,
+% and both engines are basically stable and frozen.
+%
+% At some point Hartmut and I started playing with \LUA\ in \PDFTEX\ but soon Taco,
+% Hartmut and I decided to start a follow up project. All the work on \LUATEX\ (and
+% later \LUAMETATEX) is done whenever there is time and without financial
+% compensation, so we have a slow but steady development track. Early in the
+% \LUATEX\ development there has been some funding for the initial transition (by
+% Taco) from \PDFTEX\ to what became the early versions of \LUATEX . You can read
+% more about the oriental \TEX\ project in other documents and articles in user
+% group journals. There has been some funded development of a library subsystem
+% (which for some reason never took off) as well as \LUAJIT\ integration (by
+% Luigi). The initial \METAPOST\ library (also done by Taco) was funded by a couple
+% of user groups. Then there are the (ongoing) font projects by GUST that got
+% funded by user groups as these were much needed for the \UNICODE\ engines.
+%
+% After the jump start, most work was and is still done in the usual \TEX\ spirit,
+% on a voluntary basis, by folks from the \CONTEXT\ community, and after a decades
+% we reached the stable version 1.00. It's one of the engines in \TEXLIVE\ and
+% Luigi makes sure it integrates well in there. We did continue and around 1.10 the
+% more of less final version was reached and \LUAMETATEX\ took off. In \LUATEX\
+% only bugs get fixed, occasionally some helpers can get added, and we might port
+% some of \LUAMETATEX\ back to its parent, when it doesn't harm compatibility.
+%
+% Already early in development some primitives were added that enhance the macro
+% language. More were added later. It's these extensions that are discussed in this
+% document. There are several documents in the \CONTEXT\ distribution that discuss
+% the (ongoing) development, right from the start, and these often contain
+% examples. For instance some of the new primitives have been introduced there,
+% complete with a rationale and examples of usage.
+%
+% Just for the record: the \CONTEXT\ group runs the build farm that is used to
+% generate binaries for all sorts of platforms. We make sure that there are always
+% versions that can be used for real production jobs. You can expect regular
+% updates as long as there are developments (of course, eventually we're done).
+%
+% \stopsubject
+
+\startsubject[title=Rationale] % ,placeholder=todo]
+
+Some words about the why and how it came. One of the early adopters of \CONTEXT\
+was Taco Hoekwater and we spent numerous trips to \TEX\ meetings all over the
+globe. He was also the only one I knew who had read the \TEX\ sources. Because
+\CONTEXT\ has always been on the edge of what is possible and at that time we
+both used it for rather advanced rendering, we also ran into the limitations. I'm
+not talking of \TEX\ features here. Naturally old school \TEX\ is not really
+geared for dealing with images of all kind, colors in all kind of color spaces,
+highly interactive documents, input methods like \XML, etc. The nice thing is
+that it offers some escapes, like specials and writes and later execution of
+programs that opened up lots of possibilities, so in practice there were no real
+limitations to what one could do. But coming up with a consistent and extensible
+(multi lingual) user interface was non trivial, because it had an impact in
+memory usage and performance. A lot could be done given some programming, as
+\CONTEXT\ \MKII\ proves, but it was not always pretty under the hood. The move to
+\LUATEX\ and \MKIV\ transferred some action to \LUA, and because \LUATEX\
+effectively was a \CONTEXT\ related project, we could easily keep them in sync.
+
+Our traveling together, meeting several times per year, and eventually email and
+intense \LUATEX\ developments (lots of Skype sessions) for a couple of years,
+gave us enough opportunity to discuss all kind of nice features not present in
+the engine. The previous century we discussed lots of them, rejected some, stayed
+with others, and I admit that forgot about most of the arguments already. Some
+that we did was already explored in \type {eetex}, some of those ended up in
+\LUATEX, and eventually what we have in \LUAMETATEX\ can been seen as the result
+of years of programming in \TEX, improving macros, getting more performance and
+efficiency out of existing \CONTEXT\ code and inspiration that we got out of the
+\CONTEXT\ community, a demanding lot, always willing to experiment with us.
+
+Once I decided to work on \LUAMETATEX\ and bind its source to the \CONTEXT\
+distribution so that we can be sure that it won't get messed up and might
+interfere with the \CONTEXT\ expectations, some more primitives saw their way
+into it. It is very easy to come up with all kind of bells and whistles but it is
+equally easy to hurt performance of an engine and what might go unnoticed in
+simple tests can really affect a macro package that depends on stability. So, what
+I did was mostly looking at the \CONTEXT\ code and wondering how to make some of
+the low level macros look more natural, also because I know that there are users
+who look into these sources. We spend a lot of time making them look consistent
+and nice and the nicer the better. Getting a better performance was seldom an
+argument because much is already as fast as can be so there is not that much to
+gain, but less clutter in tracing was an argument for some new primitives. Also,
+the fact that we soon might need to fall back on our phones to use \TEX\ a
+smaller memory footprint and less byte shuffling also was a consideration. The
+\LUAMETATEX\ memory footprint is somewhat smaller than the \LUATEX\ footprint.
+By binding \LUAMETATEX\ to \CONTEXT\ we can also guarantee that the combinations
+works as expected.
+
+I'm aware of the fact that \CONTEXT\ is in a somewhat unique position. First of
+all it has always been kind of cutting edge so its users are willing to
+experiment. There are users who immediately update and run tests, so bugs can and
+will be fixed fast. Already for a long time the community has an convenient
+infrastructure for updating and the build farm for generating binaries (also for
+other engines) is running smoothly.
+
+Then there is the \CONTEXT\ user interface that is quite consistent and permits
+extensions with staying backward compatible. Sometimes users run into old manuals
+or examples and then complain that \CONTEXT\ is not compatible but that then
+involves obsolete technology: we no longer need font and input encodings and font
+definitions are different for \OPENTYPE\ fonts. We always had an abstract backend
+model, but nowadays \PDF\ is kind of dominant and drives a lot of expectations.
+So, some of the \MKII\ commands are gone and \MKIV\ has some more. Also, as
+\METAPOST\ evolved that department in \CONTEXT\ also evolved. Think of it like
+cars: soon all are electric so one cannot expect a hole to poor in some fluid but
+gets a (often incompatible) plug instead. And buttons became touch panels. There
+is no need to use much force to steer or brake. Navigation is different, as are
+many controls. And do we need to steer ourselves a decade from now?
+
+So, just look at \TEX\ and \CONTEXT\ in the same way. A system from the nineties
+in the previous century differs from one three decades later. Demands differ,
+input differs, resources change, editing and processing moves on, and so on.
+Manuals, although still being written are seldom read from cover to cover because
+online searching replaced them. And who buys books about programming? So
+\LUAMETATEX, while still being \TEX\ also moves on, as do the way we do our low
+level coding. This makes sense because the original \TEX\ ecosystem was not made
+with a huge and complex macro package in mind, that just happened. An author was
+supposed to make a style for each document. An often used argument for using
+another macro package over \CONTEXT\ was that the later evolved and other macro
+packages would work the same forever and not change from the perspective of the
+user. In retrospect those arguments were somewhat strange because the world,
+computers, users etc.\ do change. Standards come and go, as do software politics
+and preferences. In many aspects the \TEX\ community is not different from other
+large software projects, operating system wars, library devotees, programming
+language addicts, paradigm shifts. But, don't worry, if you don't like
+\LUAMETATEX\ and its new primitives, just forget about them. The other engines
+will be there forever and are a safe bet, although \LUATEX\ already stirred up
+the pot I guess. But keep in mind that new features in the latest greatest
+\CONTEXT\ version will more and more rely on \LUAMETATEX\ being used; after all
+that is where it's made for. And this manual might help understand its users why,
+where and how the low level code differs between \MKII, \MKIV\ and \LMTX.
+
+Can we expect more new primitives than the ones introduced here? Given the amount
+of time I spend on experimenting and considering what made sense and what not,
+the answer probably is \quotation {no}, or at least \quotation {not that much}.
+As in the past no user ever requested the kind of primitives that were added, I
+don't expect users to come up with requests in the future either. Of course,
+those more closely related to \CONTEXT\ development look at it from the other
+end. Because it's there where the low level action really is, demands might still
+evolve.
+
+Hans Hagen \crlf Hasselt NL
+
+\stopsubject
+
+\stoptext
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/publications/publications-titlepage.tex b/Master/texmf-dist/doc/context/sources/general/manuals/publications/publications-titlepage.tex
index dfc53419afd..3f887dd7dec 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/publications/publications-titlepage.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/publications/publications-titlepage.tex
@@ -11,9 +11,9 @@
for i=0 upto 9 : draw pth shifted (0,2*i) ; endfor ;
) ;
- picture btx ; btx := textext("\ssbf\WORDS{\getvariable{document}{title}}") ;
- picture ctx ; ctx := textext("\ssbf\WORDS{\getvariable{document}{subtitle}}") ;
- picture dtx ; dtx := textext("\ssbf \getvariable{document}{author}") ;
+ picture btx ; btx := textext("\ssbf\WORDS{\documentvariable{title}}") ;
+ picture ctx ; ctx := textext("\ssbf\WORDS{\documentvariable{subtitle}}") ;
+ picture dtx ; dtx := textext("\ssbf \documentvariable{author}") ;
pic := pic shifted - llcorner pic ;
btx := btx shifted - llcorner btx ;
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex
index c5c99e97d8a..a95ddfd7994 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/spreadsheets/spreadsheets-mkiv.tex
@@ -749,9 +749,9 @@ will be added in the future but it all depends on usage.
\startsubject[title={Colofon}]
\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC author \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC website \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\NC copyright \NC \symbol[cc][cc-by-sa-nc] \NC \NR
\stoptabulate
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/sql/sql-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/sql/sql-mkiv.tex
index 835065ba041..27be160f7e7 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/sql/sql-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/sql/sql-mkiv.tex
@@ -580,9 +580,9 @@ In this example we typeset the (small) table):
\startsection[title=Colofon]
\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC author \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC website \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\NC copyright \NC \symbol[cc][cc-by-sa-nc] \NC \NR
\stoptabulate
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/swiglib/swiglib-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/swiglib/swiglib-mkiv.tex
index 7360c73fa6a..6d9d8af9aea 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/swiglib/swiglib-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/swiglib/swiglib-mkiv.tex
@@ -516,9 +516,9 @@ handle it \type {--parallel} can speed up the process.
\startsection[title=Colofon]
\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC author \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC website \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\NC comment \NC the swiglib infrastructure is implemented by Luigi Scarso \NC \NR
\stoptabulate
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/templates/templates-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/templates/templates-mkiv.tex
index 07dd041c3f8..e46b1de8ab8 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/templates/templates-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/templates/templates-mkiv.tex
@@ -276,9 +276,9 @@ possibility is provided.
\startsubject[title={Colofon}]
\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC author \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC website \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\NC copyright \NC \symbol[cc][cc-by-sa-nc] \NC \NR
\stoptabulate
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/tools/tools-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/tools/tools-mkiv.tex
index cd5214b3fd6..b26145d3724 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/tools/tools-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/tools/tools-mkiv.tex
@@ -116,13 +116,13 @@
draw p shifted (center Page - center p) withpen pencircle scaled 2 withcolor .5white ;
numeric dx ; dx := bbwidth(Page)/21 ;
numeric dy ; dy := bbheight(Page)/30 ;
- p := textext("\tt\bf\white\getvariable{document}{extra-1}") xsized(14*dx) ;
+ p := textext("\tt\bf\white\documentvariable{extra-1}") xsized(14*dx) ;
p := p shifted (-lrcorner p) shifted lrcorner Page shifted (-1dx,8dy) ;
draw p ;
- p := textext("\tt\bf\white\getvariable{document}{extra-2}") xsized(14*dx) ;
+ p := textext("\tt\bf\white\documentvariable{extra-2}") xsized(14*dx) ;
p := p shifted (-lrcorner p) shifted lrcorner Page shifted (-1dx,5dy) ;
draw p ;
- p := textext("\tt\bf\white\getvariable{document}{extra-3}") xsized(14*dx) ;
+ p := textext("\tt\bf\white\documentvariable{extra-3}") xsized(14*dx) ;
p := p shifted (-lrcorner p) shifted lrcorner Page shifted (-1dx,2dy) ;
draw p ;
setbounds currentpicture to Page ;
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/units/units-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/units/units-mkiv.tex
index ba4f1278752..66338497ac6 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/units/units-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/units/units-mkiv.tex
@@ -508,6 +508,40 @@ Which gives:
\stopsection
+\startsection[title={Goodies}]
+
+Here are some goodies:
+
+\startbuffer
+\type{1 } : \unit {30^2 meter per second}
+\type{2a} : \unit {30 ± 10 meter per second}
+\type{2b} : \unit {30 – 10 meter per second}
+\type{3a} : \unit {30^2 ± 10^2 meter per second}
+\type{3b} : \unit {30^2 – 10^2 meter per second}
+\type{4 } : \unit {30 (10) meter per second}
+\type{5a} : \unit {30 (± 10) meter per second}
+\type{5b} : \unit {30^2 (± 10^2) meter per second}
+\type{6a} : \unit {(30 ± 10) meter per second}
+\type{6b} : \unit {(30^2 ± 10^2) meter per second}
+\type{6c} : \unit {(30^2 – 10^2) meter per second}
+\type{7a} : \unit {(30 ± 10)^2 meter per second}
+\type{7b} : \unit {(30 – 10)^2 meter per second}
+\type{7c} : \unit {(30^2 – 10^3)^5 meter per second}
+\stopbuffer
+
+Instead of \type {±} one can use \type {pm} and \type {to} can be used instead of
+\type {–}.
+
+\typebuffer
+
+Their rendering explains their intention:
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopsection
+
\startsection[title={Built in keywords}]
A given sequence of keywords is translated in an list of internal
@@ -541,12 +575,14 @@ These are also special:
\showunits[packaged]
+\stopsection
+
\startsection[title={Colofon}]
\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC author \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC website \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\NC copyright \NC \symbol[cc][cc-by-sa-nc] \NC \NR
\stoptabulate
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-mkiv.tex
index a6d29ac429c..dffc7d65cd2 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-mkiv.tex
@@ -46,6 +46,7 @@
\component workflows-xml
\component workflows-setups
\component workflows-synctex
+ \component workflows-parallel
\stopbodymatter
\stopdocument
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-parallel.tex b/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-parallel.tex
new file mode 100644
index 00000000000..632d2e3e666
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-parallel.tex
@@ -0,0 +1,123 @@
+% language=us
+
+\startcomponent workflows-parallel
+
+\environment workflows-style
+
+\startchapter[title={Parallel processing}]
+
+% \startsection[title={Introduction}]
+
+% \stopsection
+
+This is just a small intermezzo. Mid April 2020 Mojca asked on the mailing list how
+to best compile 5000 files, based on a template. The answer depends on the workflow
+and circumstances but one can easily come up with some factors that play a role.
+
+\startitemize
+ \startitem
+ How complex is the document? How many pages are generated, how many fonts
+ get used? Do we need multiple runs per document? Are images involved and
+ if so, what format are they in? When processing relative small files we
+ normally need seconds, not minutes.
+ \stopitem
+ \startitem
+ What machine is used? How powerful is the \CPU, how many cores are
+ available and how much memory do we have? Is the filesystem on a local
+ \SSD\ or on a remote file system? How well does file caching work? Again,
+ we're talking seconds here.
+ \stopitem
+ \startitem
+ What engine is used? Assuming that \MKIV\ is used, we can choose for
+ \LUATEX\ or \LUAMETATEX. The former has faster backend code, the later a
+ faster frontend. What is more efficient depends on the document. The
+ later has some advantages that we will not mention here.
+ \stopitem
+\stopitemize
+
+The tests mentioned below are run with a simple \LUA\ script that manages the
+parallel runs. More about that later. As sample document we use this:
+
+\starttyping
+\setupbodyfont[dejavu]
+
+\starttext
+ \dorecurse{\getdocumentargument{noffiles}}{\input tufte\par}
+\stoptext
+\stoptyping
+
+We start with 100 runs of 10 inclusions. We permit 8 runs in parallel. A \LUATEX\
+run of 100 takes 32 seconds, a \LUAJITTEX\ run uses 26 seconds, and \LUAMETATEX\
+does it in 25 seconds. \footnote {I used a mingw cross compiled 64 bit binary;
+the GCC9 version seems somewhat slower than the previous compiler version.} An
+interesting observation is memory consumption: \LUAJITTEX, which has a different
+virtual machine and a limited memory model, peaks at 0.8GB for the eight parallel
+runs. The \LUAMETATEX\ engine has the same demands. However, \LUATEX\ needs
+1.2GB. Bumping to 20 inclusions increased the runtime a few seconds for each
+engine.
+
+The differences can be explained by a faster startup time of \LUAMETATEX; for
+instance we don't use a compressed format (dump), but there are some other
+optimizations too, and even when they're close to unmeasurable, they might add
+up. The \LUAJITTEX\ engine speeds up \LUA\ interpretation which is reflected in
+runtime because \CONTEXT\ spends half its time in \LUA.
+
+As a next test I decided to run the test file 5000 times: Mojca's scenario.
+Including 10 sample files (per run) for those 5000 files took 1320 seconds. When
+we cache the included file we gain some 5~percent.
+
+Does it matter how many jobs we run in parallel? The 2013 laptop I used for
+testing has four real cores that hyperthread to eight cores. \footnote {The
+machine has an Intel i7-3840QM \CPU, 16GB of memory and a 512 GB Samsung Pro
+\SSD.} On 1000 jobs we need 320 seconds for 1000 files (10 inclusions) when we
+use four cores. With six cores we need 270 seconds, which is much better. With
+eight cores we go down to 260 seconds and ten cores, which is two more than there
+are, we get about the same runtime. \footnote {On a more modern system, let alone
+a desktop computer, I expect these numbers to be much lower.} A \TEX\ program is
+a single core process and it makes no sense to use more cores than the \CPU\
+provides.
+
+\starttyping
+\setupbodyfont[dejavu]
+
+\starttext
+ \dorecurse{\getdocumentargument{noffiles}}{\samplefile{tufte}\par}
+\stoptext
+\stoptyping
+
+Again, caching the input file as above saves a little bit: 10 seconds, so we get
+250 seconds. When you run these tests on the machine that you normally work on,
+waiting for that many jobs to finish is no fun, so what if we (as I then normally
+do) watch some music video? With a fullscreen high resolution video shown in the
+foreground the runtime didn't change: still 250 seconds for 1000 jobs with eight
+parallel runs. On the other hand, a test with Firefox, which is quite demanding,
+running a video in the background, made the runtime going up by 30 seconds to
+280. So, when doing some networking, decompression, all kinds of unknown tracking
+using \JAVASCRIPT, etc.\ and therefore its own demands on cores and memory you
+might want to limit the number of parallel runs. These tests are probably not
+that meaningful but a good distraction when in lock down.
+
+I'm still not sure if I should come up with a script for managing these parallel
+runs. But one thing I have added to the \type {context} runner is the (for now
+undocumented) option
+
+\starttyping
+--wipebusy
+\stoptyping
+
+which, after a run removes the file
+
+\starttyping
+context-is-busy.tmp
+\stoptyping
+
+This permits a management script to check if a run is done. Before starting a run
+(in a separate process) the script can write that file and by just checking if it
+is still there, the management script can decide when a next run can be started.
+
+\stopchapter
+
+\stopcomponent
+
+% downloaded video : Jojo Mayer's 2019 TED talk: https://www.youtube.com/watch?v=Npq-bhz1ll0}
+% realtime video : Andrew Cuomo's daily press conference on dealing with Covid 19
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-commands.tex b/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-commands.tex
index ab998989542..8d9e9ef47ca 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-commands.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-commands.tex
@@ -309,6 +309,10 @@ You can restrict flushing by using commands that accept a specification.
returns the index (position) in the parent node of \cmdinternal {cd:node}
\stopxmlcmd
+\startxmlcmd {\cmdbasicsetup{xmldepth}}
+ returns the depth in the tree of \cmdinternal {cd:node}
+\stopxmlcmd
+
\startxmlcmd {\cmdbasicsetup{xmlconcat}}
returns the sequence of nodes that match \cmdinternal {cd:lpath} at
\cmdinternal {cd:node} whereby \cmdinternal {cd:text} is put between each
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-expressions.tex b/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-expressions.tex
index 0c126f2f89d..b063cab5408 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-expressions.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-expressions.tex
@@ -460,6 +460,7 @@ but that is hardly noticeable.
\NC \type {last()} \NC content \NC processes the last instance of the found element \NC \NR
\NC \type {concat(...)} \NC content \NC concatinates the match \NC \NC \NR
\NC \type {concatrange(from,to,...)} \NC content \NC concatinates a range of matches \NC \NC \NR
+\NC \type {depth()} \NC number \NC the depth in the tree of the found element \NC \NC \NR
\stoptabulate
The extra arguments of the concatinators are: \type {separator} (string), \type
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex
index 1b878e5cbae..d79c14aceaf 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex
@@ -1621,9 +1621,9 @@ in the distribution.
\startsection[title={Colofon}]
\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC author \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC website \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\NC copyright \NC \symbol[cc][cc-by-sa-nc] \NC \NR
\stoptabulate