summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/context
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2024-02-27 16:48:07 +0000
committerKarl Berry <karl@freefriends.org>2024-02-27 16:48:07 +0000
commitff3b6d10a05ce9bffa52a27ffa6e11e5ecf22c72 (patch)
tree35152df3770855d042b005decdfa9d63b686f446 /Master/texmf-dist/doc/context
parent4624d267ff83f197bbce4cf296d291465069296c (diff)
context 2024.02.27 09:18, and luametatex
git-svn-id: svn://tug.org/texlive/trunk@70189 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/context')
-rw-r--r--Master/texmf-dist/doc/context/README.adoc18
-rw-r--r--Master/texmf-dist/doc/context/context-readme.txt74
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/cld-mkiv.pdfbin692894 -> 688948 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/colors-mkiv.pdfbin2319397 -> 4568797 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-accuracy.pdfbin0 -> 42897 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-alignments.pdfbin81652 -> 89475 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-grouping.pdfbin28352 -> 52745 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-lines.pdfbin0 -> 423890 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-loops.pdfbin43942 -> 48884 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-macros.pdfbin88829 -> 119512 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-paragraphs.pdfbin296768 -> 299328 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-registers.pdfbin46958 -> 58263 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/luametatex.pdfbin1470739 -> 1497909 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/musings.pdfbin2144254 -> 2378758 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/ontarget.pdfbin539819 -> 1920631 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/pdfmerge.pdfbin0 -> 67294 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/primitives.pdfbin161106 -> 628972 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/manuals/sql-mkiv.pdfbin53962 -> 49685 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-de.pdfbin845580 -> 845252 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-en.pdfbin848669 -> 848819 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-fr.pdfbin843783 -> 843645 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-it.pdfbin844753 -> 844777 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-de.pdfbin319913 -> 320169 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-en.pdfbin317685 -> 317647 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-fr.pdfbin321113 -> 321360 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-it.pdfbin319712 -> 319765 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-nl.pdfbin319146 -> 319350 bytes
-rw-r--r--Master/texmf-dist/doc/context/documents/general/qrcs/setup-nl.pdfbin840670 -> 840533 bytes
-rw-r--r--Master/texmf-dist/doc/context/presentations/context/2017/context-2017-features-spacetest.tex2
-rw-r--r--Master/texmf-dist/doc/context/presentations/examples/present-steps-001.pdfbin12778 -> 17674 bytes
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/context.html14
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/context.man22
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/context.xml28
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/luatools.man78
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/luatools.xml31
-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.html14
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.man22
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-context.xml28
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.html53
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.man42
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.xml20
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.html (renamed from Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.html)11
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.man36
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.xml18
-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-fixpdf.html (renamed from Master/texmf-dist/doc/context/scripts/mkiv/luatools.html)34
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.man57
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.xml27
-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.html1
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.man5
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.xml1
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.html60
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.man (renamed from Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.man)26
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.xml39
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.html57
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.man54
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.xml24
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-interface.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.html68
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.man61
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.xml44
-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.html8
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.man18
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.xml13
-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-spell.man2
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.html52
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.man39
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.xml19
-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.xml17
-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/manuals/cld/cld-afewdetails.tex16
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-nicetoknow.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/colors/colors-graphics.tex180
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-compact.tex517
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-introduction.tex19
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-math.tex12
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-mkiv.tex1
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/graphics/graphics.tex18
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-accuracy.tex335
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-alignments.tex177
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex1
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-grouping.tex321
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-lines.tex1178
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-loops.tex91
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-macros.tex530
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-paragraphs.tex24
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-registers.tex208
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-style.tex5
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-building.tex18
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex76
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-fonts.tex40
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex11
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex194
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-modifications.tex38
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex13
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-style.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex.tex37
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex-lua.tex147
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luatex/luatex.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/math/math-tweaks.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/mathml/envexamp.tex9
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/eutypon-gr-e-blog-21-02-13-why-i-do-not-like-luatex.pngbin0 -> 163995 bytes
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-assumptions.tex141
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-deserved.tex356
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-dontusetex.tex201
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-history.tex294
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-introduction.tex14
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-manuals.tex236
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-perfection.tex124
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-performance.tex382
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-plain.tex11
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-style.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-treasures.tex201
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-unicode.tex30
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/musings/musings.tex20
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-accuracy.tex198
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-active.tex252
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-bars.tex204
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-constants.tex220
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-envelopes.tex914
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-gettingridof.tex4
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-green.tex204
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-introduction.tex8
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-jmn.tex245
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-math.tex20
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-mathfonts.tex1247
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-nostalgic-pgc.pdfbin0 -> 11985 bytes
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-nostalgic.tex268
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-profiles.tex507
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-radicals.tex160
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-standardize.tex987
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-style.tex5
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget.tex25
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/pdfmerge/pdfmerge-testfiles.zipbin0 -> 116288 bytes
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/pdfmerge/pdfmerge.tex604
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/primitives/primitives.tex12100
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-graphics.tex36
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-parallel.tex121
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-titlepage.tex2
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv.tex2
170 files changed, 24017 insertions, 1855 deletions
diff --git a/Master/texmf-dist/doc/context/README.adoc b/Master/texmf-dist/doc/context/README.adoc
deleted file mode 100644
index 130aa717025..00000000000
--- a/Master/texmf-dist/doc/context/README.adoc
+++ /dev/null
@@ -1,18 +0,0 @@
-== ConTeXt source code
-
-This repository hosts ConTeXt, a TeX macro package. There are three versions:
-
-MkII:: the frozen version meant for pdfTeX
-MkIV:: the mostly frozen version meant for LuaTeX
-MkXL:: the latest version running on LuaMetaTeX
-
-Here we collect all the file needed to run ConTeXt, including the sources of
-LuaMetaTeX. More information can be found on the wiki:
-
-* https://wiki.contextgarden.net
-
-For support there is a mailing list available ntg-context@ntg.nl
-
-* https://www.ntg.nl/mailman/listinfo/ntg-context
-
-Hans Hagen
diff --git a/Master/texmf-dist/doc/context/context-readme.txt b/Master/texmf-dist/doc/context/context-readme.txt
new file mode 100644
index 00000000000..771c31bae9c
--- /dev/null
+++ b/Master/texmf-dist/doc/context/context-readme.txt
@@ -0,0 +1,74 @@
+Welcome to context,
+
+The standalone context distribution has the following structure. Installations
+like texlive use a different organization.
+
+ tex/texmf-context : the files in this tree (zip)
+ tex/texmf-<platform>/bin : the tex binaries and runners
+ tex/texmf-modules : optional user installed modules
+ tex/texmf-project : user project files
+ tex/texmf-fonts/data/<collection> : user installed fonts
+
+There is only one binary: luametatex, two if you also have luatex, so the amount
+of binary code is rather small. The mtxrun and context runners (stubs) are links
+but when that doesn't work you can make copies luametatex (which is not that
+large anyway). Because luametatex is also its own runner, there are no
+dependencies on other binaries.
+
+ luametatex[.exe] : the main tex binary, also runner [around 3MB]
+
+ mtxrun[.exe] : a (sym)link to luametatex
+ context[.exe] : a (sym)link to luametatex
+
+ mtxrun.lua : the main runner code
+ context.lua : the context runner code
+
+ luatex[.exe] : optional
+
+The lua files have to be alongside its runner. Wrapping a runner in some launcher
+makes no sense and is not supported. The whole idea is to have one single
+independent framework that is the same on all main platforms (windows, linux,
+osx). The mtxrun runner also handles the other mtx-* scripts that are in the
+context tree, which is why we have only a few files in the binary path. It also
+reduces the risk for clashes in binary names.
+
+Once the bin path is added to the PATH environment variable the commands:
+
+ context
+ mtxrun
+
+will manage your tex runs. For example:
+
+ mtxrun --generate
+ mtxrun --script fonts --reload
+
+ context --make
+ context --make pdftex
+ context --make luatex
+
+ context foo.tex
+ context --pdftex foo.tex
+ context --luatex foo.tex
+
+When mkii (with pdftex or xetex) is used the texexec ruby script is launched. By
+using the runners the likelyhood of a clash with other program in a tex
+distriubution is minimized. Other ways of running context and its related scripts
+is not officially supported by the:
+
+An installation can be done using the installer but also by unzipping the archive
+or fetching from github (contextgarden). You can, if needed, compile the binary
+yourself from the includes source code.
+
+All tex resources (macros, styles, fonts, patterns, etc.) are located relative
+to the binary path so you only need to make sure that the binary is in the path.
+
+The project and font trees can be shared (using links) and are untouched by the
+installers. By keeping fonts in the tree you retain stability, By using the
+project tree you can make sure that your styles are found when you process files
+outside the tex tree.
+
+After installing you need to run 'mtxrun --generate' so that a successive
+'context' run can find the files it needs.
+
+You can get help and more information on the context garden, mailing lists and user
+forums cq. platforms.
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 bb92f9aff0f..e037684dd0e 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/colors-mkiv.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/colors-mkiv.pdf
index e52eed2f05d..0c502246541 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/colors-mkiv.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/colors-mkiv.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-accuracy.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-accuracy.pdf
new file mode 100644
index 00000000000..cdeb62fd069
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-accuracy.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-alignments.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-alignments.pdf
index 1dcc320c788..d382069f0fc 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-alignments.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-alignments.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
index 1289c75028a..1bda16578af 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-grouping.pdf
+++ 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-lines.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-lines.pdf
new file mode 100644
index 00000000000..cbcd0bd5b27
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-lines.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-loops.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-loops.pdf
index 48a619793f7..7f55fd37a3a 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-loops.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-loops.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
index a33a3b659ae..7d21b16c7b4 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-macros.pdf
+++ 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
index 11c70780f50..ddd7a3281ac 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-paragraphs.pdf
+++ 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-registers.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-registers.pdf
index 9b0b5a7cbd6..503a1d4e6ca 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-registers.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-registers.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 a6c0d6c4202..d6ffc80c026 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/musings.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/musings.pdf
index a02e1b6a1da..e19138bc6c7 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/musings.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/musings.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/ontarget.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/ontarget.pdf
index c8c3fe85458..639d13f7967 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/ontarget.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/ontarget.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/documents/general/manuals/pdfmerge.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/pdfmerge.pdf
new file mode 100644
index 00000000000..75d3f21ebc1
--- /dev/null
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/pdfmerge.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
index c465be6cb58..fdce9321f69 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/primitives.pdf
+++ 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/sql-mkiv.pdf b/Master/texmf-dist/doc/context/documents/general/manuals/sql-mkiv.pdf
index 57f6a9dc06f..7ebb6600f27 100644
--- a/Master/texmf-dist/doc/context/documents/general/manuals/sql-mkiv.pdf
+++ b/Master/texmf-dist/doc/context/documents/general/manuals/sql-mkiv.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 0da977ac590..8a03859f6b0 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 ee5d4853c99..989f3e3b8b9 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 3a591a59333..19a367c9cfa 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 2c0b57b9287..4620bb0ad88 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-de.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-mapping-de.pdf
index 0cdae12ff26..22d26a7663a 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 9a9f8ae7104..18e78ea49c9 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 272ec4b153f..9ae1c81f27b 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 c81c8a05b14..51bde3456a5 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 d5728f047ae..d2d7b31e226 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-nl.pdf b/Master/texmf-dist/doc/context/documents/general/qrcs/setup-nl.pdf
index af3e99f3f89..618bd191581 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/presentations/context/2017/context-2017-features-spacetest.tex b/Master/texmf-dist/doc/context/presentations/context/2017/context-2017-features-spacetest.tex
index 48ad4e32f8c..5b7fc2f4163 100644
--- a/Master/texmf-dist/doc/context/presentations/context/2017/context-2017-features-spacetest.tex
+++ b/Master/texmf-dist/doc/context/presentations/context/2017/context-2017-features-spacetest.tex
@@ -27,7 +27,7 @@
\starttext
-\enabledirectives[fonts.injections.useitalics] % use italic kerns for tracing
+\enabledirectives[fonts.injections.usespacefontkerns]
\definecolor[tgray][s=.5,t=.5,a=1] \showfontkerns \showfontitalics \showglyphs
diff --git a/Master/texmf-dist/doc/context/presentations/examples/present-steps-001.pdf b/Master/texmf-dist/doc/context/presentations/examples/present-steps-001.pdf
index c9ad7561330..2a31ec44c7f 100644
--- a/Master/texmf-dist/doc/context/presentations/examples/present-steps-001.pdf
+++ b/Master/texmf-dist/doc/context/presentations/examples/present-steps-001.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/context.html b/Master/texmf-dist/doc/context/scripts/mkiv/context.html
index 035e3a7db88..95dcdee75b7 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.04</title>
+ <title>ConTeXt Process Management 1.06</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.04 </div>
+ <div id="top-two">ConTeXt Process Management 1.06 </div>
</div>
</div>
<div id="bottom"> <div id="bottom-one">
@@ -60,13 +60,14 @@
<tr><th>--result</th><td>name</td><td>rename the resulting output to the given name</td></tr>
<tr><th>--trackers</th><td>list</td><td>set tracker variables (show list with --showtrackers)</td></tr>
<tr><th>--directives</th><td>list</td><td>set directive variables (show list with --showdirectives)</td></tr>
- <tr><th>--silent</th><td>list</td><td>disable logcatgories (show list with --showlogcategories)</td></tr>
+ <tr><th>--silent</th><td>list</td><td>disable logcategories (show list with --showlogcategories)</td></tr>
<tr><th>--strip</th><td></td><td>strip Lua code (only meant for production where no errors are expected)</td></tr>
<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>--find</th><td>string</td><td>search for the given pattern in the documentation sources</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--forcexml</th><td></td><td>force xml stub</td></tr>
<tr><th>--forcecld</th><td></td><td>force cld (context lua document) stub</td></tr>
@@ -101,6 +102,9 @@
<tr><th/><td/><td/></tr>
<tr><th>--global</th><td></td><td>assume given file present elsewhere</td></tr>
<tr><th>--nofile</th><td></td><td>use dummy file as jobname</td></tr>
+ <tr><th>--forceinput</th><td></td><td>use this file as input file instead of the given one</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--expert</th><td></td><td>show some more options</td></tr>
<tr><th colspan="3">expert</th></tr>
<tr><th/><td/><td/></tr>
<tr><th>--touch</th><td></td><td>update context version number (also provide --expert, optionally provide --basepath)</td></tr>
@@ -110,6 +114,7 @@
<tr><th>--keeptuc</th><td></td><td>keep previous tuc files (jobname-tuc-[run].tmp)</td></tr>
<tr><th>--keeppdf</th><td></td><td>keep previous pdf files (jobname-pdf-keep.tmp)</td></tr>
<tr><th>--keeplog</th><td></td><td>keep previous log files (jobname-log-[run].tmp)</td></tr>
+ <tr><th>--notuc</th><td></td><td>don't write a tuc file</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>
@@ -127,6 +132,9 @@
<tr><th/><td/><td/></tr>
<tr><th>--pipe</th><td></td><td>do not check for file and enter scroll mode (--dummyfile=whatever.tmp)</td></tr>
<tr><th/><td/><td/></tr>
+ <tr><th>--parallel</th><td></td><td>process multiple files at the same time (you can specify a number of processes, default: 8)</td></tr>
+ <tr><th>--parallellist</th><td></td><td>process commands in this file (lines that start with 'context')</td></tr>
+ <tr><th/><td/><td/></tr>
<tr><th>--sandbox</th><td></td><td>process file in a limited environment</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--addbinarypath</th><td></td><td>prepend the (found) binarypath to runners</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 9a36d403c2b..150517dda7c 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-2023" "version 1.04" "ConTeXt Process Management"
+.TH "mtx-context" "1" "01-01-2024" "version 1.05" "ConTeXt Process Management"
.SH NAME
mtx-context - ConTeXt Process Management
.SH SYNOPSIS
@@ -63,7 +63,7 @@ set tracker variables (show list with --showtrackers)
set directive variables (show list with --showdirectives)
.TP
.B --silent=list
-disable logcatgories (show list with --showlogcategories)
+disable logcategories (show list with --showlogcategories)
.TP
.B --strip
strip Lua code (only meant for production where no errors are expected)
@@ -83,6 +83,9 @@ don't create a dummy file (can confuse pdf viewers that keep file in view)
.B --purgeresult
purge result file before run
.TP
+.B --find=string
+search for the given pattern in the documentation sources
+.TP
.B --forcexml
force xml stub
.TP
@@ -154,6 +157,12 @@ assume given file present elsewhere
.TP
.B --nofile
use dummy file as jobname
+.TP
+.B --forceinput
+use this file as input file instead of the given one
+.TP
+.B --expert
+show some more options
.SH OPTIONS: EXPERT
.TP
.B --touch
@@ -177,6 +186,9 @@ keep previous pdf files (jobname-pdf-keep.tmp)
.B --keeplog
keep previous log files (jobname-log-[run].tmp)
.TP
+.B --notuc
+don't write a tuc file
+.TP
.B --lmtx
force lmtx mode (when available)
.TP
@@ -211,6 +223,12 @@ process file with texexec
.B --pipe
do not check for file and enter scroll mode (--dummyfile=whatever.tmp)
.TP
+.B --parallel
+process multiple files at the same time (you can specify a number of processes, default: 8)
+.TP
+.B --parallellist
+process commands in this file (lines that start with 'context')
+.TP
.B --sandbox
process file in a limited environment
.TP
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/context.xml b/Master/texmf-dist/doc/context/scripts/mkiv/context.xml
index bf341c21a9f..bd585a703de 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.04</entry>
+ <entry name="version">1.05</entry>
<entry name="comment">external helpinfo file</entry>
</metadata>
<flags>
@@ -68,7 +68,7 @@
<short>set directive variables (show list with <ref name="showdirectives"/>)</short>
</flag>
<flag name="silent" value="list">
- <short>disable logcatgories (show list with <ref name="showlogcategories"/>)</short>
+ <short>disable logcategories (show list with <ref name="showlogcategories"/>)</short>
</flag>
<flag name="strip">
<short>strip Lua code (only meant for production where no errors are expected)</short>
@@ -88,6 +88,9 @@
<flag name="purgeresult">
<short>purge result file before run</short>
</flag>
+ <flag name="find" value="string">
+ <short>search for the given pattern in the documentation sources</short>
+ </flag>
</subcategory>
<subcategory>
<flag name="forcexml">
@@ -177,9 +180,17 @@
<flag name="global">
<short>assume given file present elsewhere</short>
</flag>
- <flag name="nofile">
+ <flag name="nofile">
<short>use dummy file as jobname</short>
</flag>
+ <flag name="forceinput">
+ <short>use this file as input file instead of the given one</short>
+ </flag>
+ </subcategory>
+ <subcategory>
+ <flag name="expert">
+ <short>show some more options</short>
+ </flag>
</subcategory>
</category>
<category name="expert">
@@ -208,6 +219,9 @@
<flag name="keeplog">
<short>keep previous log files (jobname-log-[run].tmp)</short>
</flag>
+ <flag name="notuc">
+ <short>don't write a tuc file</short>
+ </flag>
<flag name="lmtx">
<short>force lmtx mode (when available)</short>
</flag>
@@ -253,6 +267,14 @@
</flag>
</subcategory>
<subcategory>
+ <flag name="parallel">
+ <short>process multiple files at the same time (you can specify a number of processes, default: 8)</short>
+ </flag>
+ <flag name="parallellist">
+ <short>process commands in this file (lines that start with 'context')</short>
+ </flag>
+ </subcategory>
+ <subcategory>
<flag name="sandbox">
<short>process file in a limited environment</short>
</flag>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/luatools.man b/Master/texmf-dist/doc/context/scripts/mkiv/luatools.man
deleted file mode 100644
index 58de54abfa2..00000000000
--- a/Master/texmf-dist/doc/context/scripts/mkiv/luatools.man
+++ /dev/null
@@ -1,78 +0,0 @@
-.TH "luatools" "1" "01-01-2023" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
-.SH NAME
- luatools - ConTeXt TDS Management Tool (aka luatools)
-.SH SYNOPSIS
-.B luatools [
-.I OPTIONS ...
-.B ] [
-.I FILENAMES
-.B ]
-.SH DESCRIPTION
-.B ConTeXt TDS Management Tool (aka luatools)
-.SH OPTIONS
-.TP
-.B --generate
-generate file database
-.TP
-.B --variables
-show configuration variables
-.TP
-.B --configurations
-show configuration order
-.TP
-.B --expand-braces
-expand complex variable
-.TP
-.B --expand-path
-expand variable (resolve paths)
-.TP
-.B --expand-var
-expand variable (resolve references)
-.TP
-.B --show-path
-show path expansion of ...
-.TP
-.B --var-value
-report value of variable
-.TP
-.B --find-file
-report file location
-.TP
-.B --find-path
-report path of file
-.TP
-.B --make
-[or --ini] make luatex format
-.TP
-.B --run
-[or --fmt] run luatex format
-.TP
-.B --compile
-assemble and compile lua inifile
-.TP
-.B --verbose
-give a bit more info
-.TP
-.B --all
-show all found files
-.TP
-.B --format=str
-filter cf format specification (default 'tex', use 'any' for any match)
-.TP
-.B --pattern=str
-filter variables
-.TP
-.B --trackers=list
-enable given trackers
-.SH AUTHOR
-More information about ConTeXt and the tools that come with it can be found at:
-
-
-.B "maillist:"
-ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
-
-.B "webpage:"
-http://www.pragma-ade.nl / http://tex.aanhet.net
-
-.B "wiki:"
-http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/luatools.xml b/Master/texmf-dist/doc/context/scripts/mkiv/luatools.xml
deleted file mode 100644
index 34460fffec4..00000000000
--- a/Master/texmf-dist/doc/context/scripts/mkiv/luatools.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0"?><application>
- <metadata>
- <entry name="name">luatools</entry>
- <entry name="detail">ConTeXt TDS Management Tool (aka luatools)</entry>
- <entry name="version">1.35</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="generate"><short>generate file database</short></flag>
- <flag name="variables"><short>show configuration variables</short></flag>
- <flag name="configurations"><short>show configuration order</short></flag>
- <flag name="expand-braces"><short>expand complex variable</short></flag>
- <flag name="expand-path"><short>expand variable (resolve paths)</short></flag>
- <flag name="expand-var"><short>expand variable (resolve references)</short></flag>
- <flag name="show-path"><short>show path expansion of ...</short></flag>
- <flag name="var-value"><short>report value of variable</short></flag>
- <flag name="find-file"><short>report file location</short></flag>
- <flag name="find-path"><short>report path of file</short></flag>
- <flag name="make"><short>[or <ref name="ini"/>] make luatex format</short></flag>
- <flag name="run"><short>[or <ref name="fmt"/>] run luatex format</short></flag>
- <flag name="compile"><short>assemble and compile lua inifile</short></flag>
- <flag name="verbose"><short>give a bit more info</short></flag>
- <flag name="all"><short>show all found files</short></flag>
- <flag name="format" value="str"><short>filter cf format specification (default 'tex', use 'any' for any match)</short></flag>
- <flag name="pattern" value="str"><short>filter variables</short></flag>
- <flag name="trackers" value="list"><short>enable given trackers</short></flag>
- </subcategory>
- </category>
- </flags>
-</application> \ No newline at end of file
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 851c17a7ac4..293ef2d959c 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-2023" "version 1.20" "Babel Input To UTF Conversion"
+.TH "mtx-babel" "1" "01-01-2024" "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 4a5133c13cf..b25656de69e 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-2023" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
+.TH "mtx-base" "1" "01-01-2024" "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 79aeb0ff73a..5c18226b76b 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-2023" "version 1.00" "bibtex helpers"
+.TH "mtx-bibtex" "1" "01-01-2024" "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 ab1b1293c26..fb8949e517e 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-2023" "version 1.01" "ConTeXt & MetaTeX Cache Management"
+.TH "mtx-cache" "1" "01-01-2024" "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 059d419e252..04bbcd3fb10 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-2023" "version 0.10" "MkII Character Table Generators"
+.TH "mtx-chars" "1" "01-01-2024" "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 d41ba5c45cb..d81161cae42 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-2023" "version 0.10" "Basic ConTeXt Syntax Checking"
+.TH "mtx-check" "1" "01-01-2024" "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 e072c8eda54..df4cbd19d45 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-2023" "version 0.10" "ConTeXt Color Management"
+.TH "mtx-colors" "1" "01-01-2024" "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 035e3a7db88..95dcdee75b7 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.04</title>
+ <title>ConTeXt Process Management 1.06</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.04 </div>
+ <div id="top-two">ConTeXt Process Management 1.06 </div>
</div>
</div>
<div id="bottom"> <div id="bottom-one">
@@ -60,13 +60,14 @@
<tr><th>--result</th><td>name</td><td>rename the resulting output to the given name</td></tr>
<tr><th>--trackers</th><td>list</td><td>set tracker variables (show list with --showtrackers)</td></tr>
<tr><th>--directives</th><td>list</td><td>set directive variables (show list with --showdirectives)</td></tr>
- <tr><th>--silent</th><td>list</td><td>disable logcatgories (show list with --showlogcategories)</td></tr>
+ <tr><th>--silent</th><td>list</td><td>disable logcategories (show list with --showlogcategories)</td></tr>
<tr><th>--strip</th><td></td><td>strip Lua code (only meant for production where no errors are expected)</td></tr>
<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>--find</th><td>string</td><td>search for the given pattern in the documentation sources</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--forcexml</th><td></td><td>force xml stub</td></tr>
<tr><th>--forcecld</th><td></td><td>force cld (context lua document) stub</td></tr>
@@ -101,6 +102,9 @@
<tr><th/><td/><td/></tr>
<tr><th>--global</th><td></td><td>assume given file present elsewhere</td></tr>
<tr><th>--nofile</th><td></td><td>use dummy file as jobname</td></tr>
+ <tr><th>--forceinput</th><td></td><td>use this file as input file instead of the given one</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--expert</th><td></td><td>show some more options</td></tr>
<tr><th colspan="3">expert</th></tr>
<tr><th/><td/><td/></tr>
<tr><th>--touch</th><td></td><td>update context version number (also provide --expert, optionally provide --basepath)</td></tr>
@@ -110,6 +114,7 @@
<tr><th>--keeptuc</th><td></td><td>keep previous tuc files (jobname-tuc-[run].tmp)</td></tr>
<tr><th>--keeppdf</th><td></td><td>keep previous pdf files (jobname-pdf-keep.tmp)</td></tr>
<tr><th>--keeplog</th><td></td><td>keep previous log files (jobname-log-[run].tmp)</td></tr>
+ <tr><th>--notuc</th><td></td><td>don't write a tuc file</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>
@@ -127,6 +132,9 @@
<tr><th/><td/><td/></tr>
<tr><th>--pipe</th><td></td><td>do not check for file and enter scroll mode (--dummyfile=whatever.tmp)</td></tr>
<tr><th/><td/><td/></tr>
+ <tr><th>--parallel</th><td></td><td>process multiple files at the same time (you can specify a number of processes, default: 8)</td></tr>
+ <tr><th>--parallellist</th><td></td><td>process commands in this file (lines that start with 'context')</td></tr>
+ <tr><th/><td/><td/></tr>
<tr><th>--sandbox</th><td></td><td>process file in a limited environment</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--addbinarypath</th><td></td><td>prepend the (found) binarypath to runners</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 9a36d403c2b..150517dda7c 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-2023" "version 1.04" "ConTeXt Process Management"
+.TH "mtx-context" "1" "01-01-2024" "version 1.05" "ConTeXt Process Management"
.SH NAME
mtx-context - ConTeXt Process Management
.SH SYNOPSIS
@@ -63,7 +63,7 @@ set tracker variables (show list with --showtrackers)
set directive variables (show list with --showdirectives)
.TP
.B --silent=list
-disable logcatgories (show list with --showlogcategories)
+disable logcategories (show list with --showlogcategories)
.TP
.B --strip
strip Lua code (only meant for production where no errors are expected)
@@ -83,6 +83,9 @@ don't create a dummy file (can confuse pdf viewers that keep file in view)
.B --purgeresult
purge result file before run
.TP
+.B --find=string
+search for the given pattern in the documentation sources
+.TP
.B --forcexml
force xml stub
.TP
@@ -154,6 +157,12 @@ assume given file present elsewhere
.TP
.B --nofile
use dummy file as jobname
+.TP
+.B --forceinput
+use this file as input file instead of the given one
+.TP
+.B --expert
+show some more options
.SH OPTIONS: EXPERT
.TP
.B --touch
@@ -177,6 +186,9 @@ keep previous pdf files (jobname-pdf-keep.tmp)
.B --keeplog
keep previous log files (jobname-log-[run].tmp)
.TP
+.B --notuc
+don't write a tuc file
+.TP
.B --lmtx
force lmtx mode (when available)
.TP
@@ -211,6 +223,12 @@ process file with texexec
.B --pipe
do not check for file and enter scroll mode (--dummyfile=whatever.tmp)
.TP
+.B --parallel
+process multiple files at the same time (you can specify a number of processes, default: 8)
+.TP
+.B --parallellist
+process commands in this file (lines that start with 'context')
+.TP
.B --sandbox
process file in a limited environment
.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 bf341c21a9f..bd585a703de 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.04</entry>
+ <entry name="version">1.05</entry>
<entry name="comment">external helpinfo file</entry>
</metadata>
<flags>
@@ -68,7 +68,7 @@
<short>set directive variables (show list with <ref name="showdirectives"/>)</short>
</flag>
<flag name="silent" value="list">
- <short>disable logcatgories (show list with <ref name="showlogcategories"/>)</short>
+ <short>disable logcategories (show list with <ref name="showlogcategories"/>)</short>
</flag>
<flag name="strip">
<short>strip Lua code (only meant for production where no errors are expected)</short>
@@ -88,6 +88,9 @@
<flag name="purgeresult">
<short>purge result file before run</short>
</flag>
+ <flag name="find" value="string">
+ <short>search for the given pattern in the documentation sources</short>
+ </flag>
</subcategory>
<subcategory>
<flag name="forcexml">
@@ -177,9 +180,17 @@
<flag name="global">
<short>assume given file present elsewhere</short>
</flag>
- <flag name="nofile">
+ <flag name="nofile">
<short>use dummy file as jobname</short>
</flag>
+ <flag name="forceinput">
+ <short>use this file as input file instead of the given one</short>
+ </flag>
+ </subcategory>
+ <subcategory>
+ <flag name="expert">
+ <short>show some more options</short>
+ </flag>
</subcategory>
</category>
<category name="expert">
@@ -208,6 +219,9 @@
<flag name="keeplog">
<short>keep previous log files (jobname-log-[run].tmp)</short>
</flag>
+ <flag name="notuc">
+ <short>don't write a tuc file</short>
+ </flag>
<flag name="lmtx">
<short>force lmtx mode (when available)</short>
</flag>
@@ -253,6 +267,14 @@
</flag>
</subcategory>
<subcategory>
+ <flag name="parallel">
+ <short>process multiple files at the same time (you can specify a number of processes, default: 8)</short>
+ </flag>
+ <flag name="parallellist">
+ <short>process commands in this file (lines that start with 'context')</short>
+ </flag>
+ </subcategory>
+ <subcategory>
<flag name="sandbox">
<short>process file in a limited environment</short>
</flag>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.html
new file mode 100644
index 00000000000..2eb712911e1
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>ConTeXT Graphic Conversion Helpers 0.10</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%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">ConTeXT Graphic Conversion Helpers 0.10 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--convertall</th><td></td><td>convert all graphics on path</td></tr>
+ <tr><th>--inputpath</th><td>string</td><td>original graphics path</td></tr>
+ <tr><th>--outputpath</th><td>string</td><td>converted graphics path</td></tr>
+ <tr><th>--watch</th><td></td><td>watch folders</td></tr>
+ <tr><th>--force</th><td></td><td>force conversion (even if older)</td></tr>
+ <tr><th>--delay</th><td></td><td>time between sweeps</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.man
new file mode 100644
index 00000000000..6f00ee01e0b
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.man
@@ -0,0 +1,42 @@
+.TH "mtx-convert" "1" "01-01-2024" "version 0.10" "ConTeXT Graphic Conversion Helpers"
+.SH NAME
+ mtx-convert - ConTeXT Graphic Conversion Helpers
+.SH SYNOPSIS
+.B mtxrun --script convert [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B ConTeXT Graphic Conversion Helpers
+.SH OPTIONS
+.TP
+.B --convertall
+convert all graphics on path
+.TP
+.B --inputpath=string
+original graphics path
+.TP
+.B --outputpath=string
+converted graphics path
+.TP
+.B --watch
+watch folders
+.TP
+.B --force
+force conversion (even if older)
+.TP
+.B --delay
+time between sweeps
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.xml
new file mode 100644
index 00000000000..641116c58ac
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-convert.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-convert</entry>
+ <entry name="detail">ConTeXT Graphic Conversion Helpers</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="convertall"><short>convert all graphics on path</short></flag>
+ <flag name="inputpath" value="string"><short>original graphics path</short></flag>
+ <flag name="outputpath" value="string"><short>converted graphics path</short></flag>
+ <flag name="watch"><short>watch folders</short></flag>
+ <flag name="force"><short>force conversion (even if older)</short></flag>
+ <flag name="delay"><short>time between sweeps</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.html
index 54598c8caf4..1ec6ad48980 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.html
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.html
@@ -14,7 +14,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
- <title>ConTeXt Timing Tools 0.10</title>
+ <title>Dealing with CTAN</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 Timing Tools 0.10 </div>
+ <div id="top-two">Dealing with CTAN </div>
</div>
</div>
<div id="bottom"> <div id="bottom-one">
@@ -39,9 +39,10 @@
<table>
<tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
<tr><th/><td/><td/></tr>
- <tr><th>--xhtml</th><td></td><td>make xhtml file</td></tr>
- <tr><th>--launch</th><td></td><td>launch after conversion</td></tr>
- <tr><th>--remove</th><td></td><td>remove after launching</td></tr>
+ <tr><th>--packages</th><td></td><td>list available packages [--field=key|name|caption]</td></tr>
+ <tr><th>--topics</th><td></td><td>list available topics [--field=key|name|details]</td></tr>
+ <tr><th>--details</th><td></td><td>show details about package</td></tr>
+ <tr><th>--pattern</th><td>string</td><td>use this pattern, otherwise first argument</td></tr>
</table>
<br/>
</div>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.man
new file mode 100644
index 00000000000..8f1edd6c621
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.man
@@ -0,0 +1,36 @@
+.TH "mtx-ctan" "1" "01-01-2024" "version 1.00" "Dealing with CTAN"
+.SH NAME
+ mtx-ctan - Dealing with CTAN
+.SH SYNOPSIS
+.B mtxrun --script ctan [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B Dealing with CTAN
+.SH OPTIONS
+.TP
+.B --packages
+list available packages [--field=key|name|caption]
+.TP
+.B --topics
+list available topics [--field=key|name|details]
+.TP
+.B --details
+show details about package
+.TP
+.B --pattern=string
+use this pattern, otherwise first argument
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.xml
new file mode 100644
index 00000000000..32f78ee36ff
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-ctan.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-ctan</entry>
+ <entry name="detail">Dealing with CTAN</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="packages"><short>list available packages [--field=key|name|caption]</short></flag>
+ <flag name="topics"><short>list available topics [--field=key|name|details]</short></flag>
+ <flag name="details"><short>show details about package</short></flag>
+ <flag name="pattern" value="string"><short>use this pattern, otherwise first argument</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
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 6719dc72c9a..fec258b7399 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-2023" "version 0.01" "ConTeXt DVI Helpers"
+.TH "mtx-dvi" "1" "01-01-2024" "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 3b53984c7b8..2b4767d2b20 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-2023" "version 1.10" "ConTeXt EPUB Helpers"
+.TH "mtx-epub" "1" "01-01-2024" "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 c415c5425a0..c366a7da6eb 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-2023" "version 1.00" "Evohome Fetcher"
+.TH "mtx-evohome" "1" "01-01-2024" "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 12ac2cd3b74..de6e98c0073 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-2023" "version 1.00" "Fast Directory Change"
+.TH "mtx-fcd" "1" "01-01-2024" "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/luatools.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.html
index af51be9d1b9..6ebda822414 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/luatools.html
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.html
@@ -14,7 +14,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
- <title>luatools 1.35</title>
+ <title>Making PDF files more compliant</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">luatools 1.35 </div>
+ <div id="top-two">Making PDF files more compliant </div>
</div>
</div>
<div id="bottom"> <div id="bottom-one">
@@ -39,24 +39,18 @@
<table>
<tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
<tr><th/><td/><td/></tr>
- <tr><th>--generate</th><td></td><td>generate file database</td></tr>
- <tr><th>--variables</th><td></td><td>show configuration variables</td></tr>
- <tr><th>--configurations</th><td></td><td>show configuration order</td></tr>
- <tr><th>--expand-braces</th><td></td><td>expand complex variable</td></tr>
- <tr><th>--expand-path</th><td></td><td>expand variable (resolve paths)</td></tr>
- <tr><th>--expand-var</th><td></td><td>expand variable (resolve references)</td></tr>
- <tr><th>--show-path</th><td></td><td>show path expansion of ...</td></tr>
- <tr><th>--var-value</th><td></td><td>report value of variable</td></tr>
- <tr><th>--find-file</th><td></td><td>report file location</td></tr>
- <tr><th>--find-path</th><td></td><td>report path of file</td></tr>
- <tr><th>--make</th><td></td><td>[or --ini] make luatex format</td></tr>
- <tr><th>--run</th><td></td><td>[or --fmt] run luatex format</td></tr>
- <tr><th>--compile</th><td></td><td>assemble and compile lua inifile</td></tr>
- <tr><th>--verbose</th><td></td><td>give a bit more info</td></tr>
- <tr><th>--all</th><td></td><td>show all found files</td></tr>
- <tr><th>--format</th><td>str</td><td>filter cf format specification (default 'tex', use 'any' for any match)</td></tr>
- <tr><th>--pattern</th><td>str</td><td>filter variables</td></tr>
- <tr><th>--trackers</th><td>list</td><td>enable given trackers</td></tr>
+ <tr><th>--uncompress</th><td></td><td>uncompress using qpdf</td></tr>
+ <tr><th>--validate</th><td></td><td>validate using verapdf</td></tr>
+ <tr><th>--check</th><td></td><td>check verification result </td></tr>
+ <tr><th>--convert</th><td></td><td>convert using context</td></tr>
+ <tr><th>--compare</th><td></td><td>compare result with original</td></tr>
+ <tr><th>--compactor</th><td></td><td>use given compactor</td></tr>
+ <tr><th>--standard</th><td></td><td>use given standard</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--pattern</th><td></td><td>processs files according to pattern</td></tr>
+ <tr><th>--silent</th><td></td><td>suppress messages</td></tr>
+ <tr><th>--once</th><td></td><td>run only once</td></tr>
+ <tr><th>--resolution</th><td></td><td>use this resolution when comparing</td></tr>
</table>
<br/>
</div>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.man
new file mode 100644
index 00000000000..24cc85aa0f6
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.man
@@ -0,0 +1,57 @@
+.TH "mtx-tools" "1" "01-01-2024" "version 1.01" "Some File Related Goodies"
+.SH NAME
+ mtx-tools - Some File Related Goodies
+.SH SYNOPSIS
+.B mtxrun --script tools [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B Some File Related Goodies
+.SH OPTIONS
+.TP
+.B --uncompress
+uncompress using qpdf
+.TP
+.B --validate
+validate using verapdf
+.TP
+.B --check
+check verification result
+.TP
+.B --convert
+convert using context
+.TP
+.B --compare
+compare result with original
+.TP
+.B --compactor
+use given compactor
+.TP
+.B --standard
+use given standard
+.TP
+.B --pattern
+processs files according to pattern
+.TP
+.B --silent
+suppress messages
+.TP
+.B --once
+run only once
+.TP
+.B --resolution
+use this resolution when comparing
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.xml
new file mode 100644
index 00000000000..0582c68e719
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-fixpdf.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-tools</entry>
+ <entry name="detail">Some File Related Goodies</entry>
+ <entry name="version">1.01</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="uncompress"><short>uncompress using qpdf</short></flag>
+ <flag name="validate"><short>validate using verapdf</short></flag>
+ <flag name="check"><short>check verification result </short></flag>
+ <flag name="convert"><short>convert using context</short></flag>
+ <flag name="compare"><short>compare result with original</short></flag>
+ <flag name="compactor"><short>use given compactor</short></flag>
+ <flag name="standard"><short>use given standard</short></flag>
+ </subcategory>
+ <subcategory>
+ <flag name="pattern"><short>processs files according to pattern</short></flag>
+ <flag name="silent"><short>suppress messages</short></flag>
+ <flag name="once"><short>run only once</short></flag>
+ <flag name="resolution"><short>use this resolution when comparing</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
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 f6981986548..8fe33278614 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-2023" "version 0.10" "ConTeXt Flac Helpers"
+.TH "mtx-flac" "1" "01-01-2024" "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 16cd7f068f0..656d70d27c7 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-2023" "version 1.00" "ConTeXt Font Database Management"
+.TH "mtx-fonts" "1" "01-01-2024" "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.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.html
index 10df98cf4e4..fa9e727b5ac 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.html
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.html
@@ -42,6 +42,7 @@
<tr><th>--pattern</th><td></td><td>search for pattern (optional)</td></tr>
<tr><th>--count</th><td></td><td>count matches only</td></tr>
<tr><th>--nocomment</th><td></td><td>skip lines that start with %% or #</td></tr>
+ <tr><th>--noattic</th><td></td><td>skip files that hh considers irrelevant</td></tr>
<tr><th>--n</th><td></td><td>show at most n matches</td></tr>
<tr><th>--first</th><td></td><td>only show first match</td></tr>
<tr><th>--match</th><td></td><td>return the match (if it is one)</td></tr>
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 5114ec7e21e..16eddae3690 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-2023" "version 0.10" "Simple Grepper"
+.TH "mtx-grep" "1" "01-01-2024" "version 0.10" "Simple Grepper"
.SH NAME
mtx-grep - Simple Grepper
.SH SYNOPSIS
@@ -20,6 +20,9 @@ count matches only
.B --nocomment
skip lines that start with %% or #
.TP
+.B --noattic
+skip files that hh considers irrelevant
+.TP
.B --n
show at most n matches
.TP
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.xml
index a78565b57cb..de8bc32a5a7 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.xml
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-grep.xml
@@ -11,6 +11,7 @@
<flag name="pattern"><short>search for pattern (optional)</short></flag>
<flag name="count"><short>count matches only</short></flag>
<flag name="nocomment"><short>skip lines that start with %% or #</short></flag>
+ <flag name="noattic"><short>skip files that hh considers irrelevant</short></flag>
<flag name="n"><short>show at most n matches</short></flag>
<flag name="first"><short>only show first match</short></flag>
<flag name="match"><short>return the match (if it is one)</short></flag>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.html
new file mode 100644
index 00000000000..c8430e57ba5
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>ConTeXt Module Installer 1.00</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%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">ConTeXt Module Installer 1.00 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--list</th><td></td><td>list modules</td></tr>
+ <tr><th>--installed</th><td></td><td>list installed modules</td></tr>
+ <tr><th>--install</th><td></td><td>install modules</td></tr>
+ <tr><th>--uninstall</th><td></td><td>uninstall modules</td></tr>
+ <tr><th>--module</th><td></td><td>install (zip) file(s)</td></tr>
+ </table>
+<br/>
+<h1>Examples</h1>
+<tt>mtxrun --script install-modules --list</tt>
+<br/><br/><tt>mtxrun --script install-modules --install filter letter</tt>
+<br/><tt>mtxrun --script install-modules --install tikz</tt>
+<br/><tt>mtxrun --script install-modules --install --all</tt>
+<br/><br/><tt>mtxrun --script install-modules --install --module t-letter.zip</tt>
+<br/><tt>mtxrun --script install-modules --uninstall --module t-letter.zip</tt>
+<br/><br/><tt>mtxrun --script install-modules --installed</tt>
+<br/><br/> </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.man
index 31b2671c99b..3adb4f3ba04 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.man
@@ -1,24 +1,30 @@
-.TH "mtx-timing" "1" "01-01-2023" "version 0.10" "ConTeXt Timing Tools"
+.TH "mtx-install" "1" "01-01-2024" "version 2.01" "ConTeXt Installer"
.SH NAME
- mtx-timing - ConTeXt Timing Tools
+ mtx-install - ConTeXt Installer
.SH SYNOPSIS
-.B mtxrun --script timing [
+.B mtxrun --script install [
.I OPTIONS ...
.B ] [
.I FILENAMES
.B ]
.SH DESCRIPTION
-.B ConTeXt Timing Tools
+.B ConTeXt Installer
.SH OPTIONS
.TP
-.B --xhtml
-make xhtml file
+.B --list
+list modules
.TP
-.B --launch
-launch after conversion
+.B --installed
+list installed modules
.TP
-.B --remove
-remove after launching
+.B --install
+install modules
+.TP
+.B --uninstall
+uninstall modules
+.TP
+.B --module
+install (zip) file(s)
.SH AUTHOR
More information about ConTeXt and the tools that come with it can be found at:
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.xml
new file mode 100644
index 00000000000..cee53e9126c
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install-modules.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-install</entry>
+ <entry name="detail">ConTeXt Installer</entry>
+ <entry name="version">2.01</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="list"><short>list modules</short></flag>
+ <flag name="installed"><short>list installed modules</short></flag>
+ <flag name="install"><short>install modules</short></flag>
+ <flag name="uninstall"><short>uninstall modules</short></flag>
+ <flag name="module"><short>install (zip) file(s)</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Examples</title>
+ <subcategory>
+ <example><command>mtxrun --script install-modules --list</command></example>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script install-modules --install filter letter</command></example>
+ <example><command>mtxrun --script install-modules --install tikz</command></example>
+ <example><command>mtxrun --script install-modules --install --all</command></example>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script install-modules --install --module t-letter.zip</command></example>
+ <example><command>mtxrun --script install-modules --uninstall --module t-letter.zip</command></example>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script install-modules --installed</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.html
new file mode 100644
index 00000000000..dc08c4837df
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.html
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>ConTeXt Installer 2.01</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%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">ConTeXt Installer 2.01 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--platform</th><td>string</td><td>platform</td></tr>
+ <tr><th>--server</th><td>string</td><td>repository url (rsync://contextgarden.net)</td></tr>
+ <tr><th>--modules</th><td>string</td><td>extra modules (can be list or 'all')</td></tr>
+ <tr><th>--fonts</th><td>string</td><td>additional fonts (can be list or 'all')</td></tr>
+ <tr><th>--goodies</th><td>string</td><td>extra binaries (like scite and texworks)</td></tr>
+ <tr><th>--install</th><td></td><td>install context</td></tr>
+ <tr><th>--update</th><td></td><td>update context</td></tr>
+ <tr><th>--erase</th><td></td><td>wipe the cache</td></tr>
+ <tr><th>--identify</th><td></td><td>create list of files</td></tr>
+ <tr><th>--secure</th><td></td><td>use curl for https</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.man
new file mode 100644
index 00000000000..bb99a481402
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.man
@@ -0,0 +1,54 @@
+.TH "mtx-install" "1" "01-01-2024" "version 2.01" "ConTeXt Installer"
+.SH NAME
+ mtx-install - ConTeXt Installer
+.SH SYNOPSIS
+.B mtxrun --script install [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B ConTeXt Installer
+.SH OPTIONS
+.TP
+.B --platform=string
+platform
+.TP
+.B --server=string
+repository url (rsync://contextgarden.net)
+.TP
+.B --modules=string
+extra modules (can be list or 'all')
+.TP
+.B --fonts=string
+additional fonts (can be list or 'all')
+.TP
+.B --goodies=string
+extra binaries (like scite and texworks)
+.TP
+.B --install
+install context
+.TP
+.B --update
+update context
+.TP
+.B --erase
+wipe the cache
+.TP
+.B --identify
+create list of files
+.TP
+.B --secure
+use curl for https
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.xml
new file mode 100644
index 00000000000..a7dd8631c3c
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-install.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-install</entry>
+ <entry name="detail">ConTeXt Installer</entry>
+ <entry name="version">2.01</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="platform" value="string"><short>platform</short></flag>
+ <flag name="server" value="string"><short>repository url (rsync://contextgarden.net)</short></flag>
+ <flag name="modules" value="string"><short>extra modules (can be list or 'all')</short></flag>
+ <flag name="fonts" value="string"><short>additional fonts (can be list or 'all')</short></flag>
+ <flag name="goodies" value="string"><short>extra binaries (like scite and texworks)</short></flag>
+ <flag name="install"><short>install context</short></flag>
+ <flag name="update"><short>update context</short></flag>
+ <flag name="erase"><short>wipe the cache</short></flag>
+ <flag name="identify"><short>create list of files</short></flag>
+ <flag name="secure"><short>use curl for https</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
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 f8aa9020642..a906a1a1c38 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-2023" "version 0.13" "ConTeXt Interface Related Goodies"
+.TH "mtx-interface" "1" "01-01-2024" "version 0.13" "ConTeXt Interface Related Goodies"
.SH NAME
mtx-interface - ConTeXt Interface Related Goodies
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.html
new file mode 100644
index 00000000000..1da2382da12
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>ConTeXt KPSE checking utility</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%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">ConTeXt KPSE checking utility </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th colspan="3">basic</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--progname</th><td></td><td>mandate, set the program name (e.g. pdftex)</td></tr>
+ <tr><th>--findfile</th><td></td><td>report the fully qualified path of the given file</td></tr>
+ <tr><th>--findfiles</th><td></td><td>report a list of all full names of the given file</td></tr>
+ <tr><th>--expandpath</th><td></td><td>expand the given path variable</td></tr>
+ <tr><th>--expandvar</th><td></td><td>expand a variable</td></tr>
+ <tr><th>--expandbraces</th><td></td><td>expand a complex variable specification</td></tr>
+ <tr><th>--varvalue</th><td></td><td>show the value of a variable</td></tr>
+ <tr><th>--readablefile</th><td></td><td>report if a file is readable</td></tr>
+ <tr><th>--filetypes</th><td></td><td>list all supported formats</td></tr>
+ <tr><th colspan="3">additional</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--format</th><td></td><td>format type</td></tr>
+ <tr><th>--path</th><td></td><td>path variable</td></tr>
+ <tr><th>--split</th><td></td><td>split result in lines</td></tr>
+ </table>
+<br/>
+<h1>Examples</h1>
+<tt>mtxrun --script kpse --progname=pdftex --findfile context.mkii</tt>
+<br/><tt>mtxrun --script kpse --progname=pdftex --findfile context.mkii --format=tex</tt>
+<br/><tt>mtxrun --script kpse --progname=pdftex --findfiles context.mkii --path=$TEXINPUTS</tt>
+<br/><br/><tt>mtxrun --script kpse --progname=pdftex --expandpath $TEXMFVAR</tt>
+<br/><tt>mtxrun --script kpse --progname=pdftex --expandpath $TEXINPUTS -- split</tt>
+<br/><br/> </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.man
new file mode 100644
index 00000000000..6690cbdd479
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.man
@@ -0,0 +1,61 @@
+.TH "mtx-kpse" "1" "01-01-2024" "version 1.00" "ConTeXt KPSE checking utility"
+.SH NAME
+ mtx-kpse - ConTeXt KPSE checking utility
+.SH SYNOPSIS
+.B mtxrun --script kpse [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B ConTeXt KPSE checking utility
+.SH OPTIONS: BASIC
+.TP
+.B --progname
+mandate, set the program name (e.g. pdftex)
+.TP
+.B --findfile
+report the fully qualified path of the given file
+.TP
+.B --findfiles
+report a list of all full names of the given file
+.TP
+.B --expandpath
+expand the given path variable
+.TP
+.B --expandvar
+expand a variable
+.TP
+.B --expandbraces
+expand a complex variable specification
+.TP
+.B --varvalue
+show the value of a variable
+.TP
+.B --readablefile
+report if a file is readable
+.TP
+.B --filetypes
+list all supported formats
+.SH OPTIONS: ADDITIONAL
+.TP
+.B --format
+format type
+.TP
+.B --path
+path variable
+.TP
+.B --split
+split result in lines
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.xml
new file mode 100644
index 00000000000..3b2259d9fb5
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-kpse.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-kpse</entry>
+ <entry name="detail">ConTeXt KPSE checking utility</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="progname"><short>mandate, set the program name (e.g. pdftex)</short></flag>
+ <flag name="findfile"><short>report the fully qualified path of the given file</short></flag>
+ <flag name="findfiles"><short>report a list of all full names of the given file</short></flag>
+ <flag name="expandpath"><short>expand the given path variable</short></flag>
+ <flag name="expandvar"><short>expand a variable</short></flag>
+ <flag name="expandbraces"><short>expand a complex variable specification</short></flag>
+ <flag name="varvalue"><short>show the value of a variable</short></flag>
+ <flag name="readablefile"><short>report if a file is readable</short></flag>
+ <flag name="filetypes"><short>list all supported formats</short></flag>
+ </subcategory>
+ </category>
+ <category name="additional">
+ <subcategory>
+ <flag name="format"><short>format type</short></flag>
+ <flag name="path"><short>path variable</short></flag>
+ <flag name="split"><short>split result in lines</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Examples</title>
+ <subcategory>
+ <example><command>mtxrun --script kpse --progname=pdftex --findfile context.mkii</command></example>
+ <example><command>mtxrun --script kpse --progname=pdftex --findfile context.mkii --format=tex</command></example>
+ <example><command>mtxrun --script kpse --progname=pdftex --findfiles context.mkii --path=$TEXINPUTS</command></example>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script kpse --progname=pdftex --expandpath $TEXMFVAR</command></example>
+ <example><command>mtxrun --script kpse --progname=pdftex --expandpath $TEXINPUTS -- split</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
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 265a203e421..338ee9fa322 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-2023" "version 0.10" "MetaPost to PDF processor"
+.TH "mtx-metapost" "1" "01-01-2024" "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 11629fedef9..5d9e481a105 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-2023" "version 1.00" "ConTeXt Module Documentation Generators"
+.TH "mtx-modules" "1" "01-01-2024" "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 33ce616ed1e..38ea0271be8 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-2023" "version 0.10" "Distribution Related Goodies"
+.TH "mtx-package" "1" "01-01-2024" "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 771c86f0a9c..8f652546524 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-2023" "version 0.20" "ConTeXt Pattern File Management"
+.TH "mtx-patterns" "1" "01-01-2024" "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.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.html
index 3e4541a0ccb..6220b6449b8 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.html
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.html
@@ -41,10 +41,14 @@
<tr><th/><td/><td/></tr>
<tr><th>--info</th><td></td><td>show some info about the given file</td></tr>
<tr><th>--metadata</th><td></td><td>show metadata xml blob</td></tr>
+ <tr><th>--formdata</th><td></td><td>show formdata</td></tr>
<tr><th>--pretty</th><td></td><td>replace newlines in metadata</td></tr>
<tr><th>--fonts</th><td></td><td>show used fonts (--detail)</td></tr>
- <tr><th>--object</th><td></td><td>show object"/></td></tr>
- <tr><th>--links</th><td></td><td>show links"/></td></tr>
+ <tr><th>--object</th><td></td><td>show object</td></tr>
+ <tr><th>--links</th><td></td><td>show links</td></tr>
+ <tr><th>--sign</th><td></td><td>sign document (assumes signature template)</td></tr>
+ <tr><th>--verify</th><td></td><td>verify document</td></tr>
+ <tr><th>--detail</th><td></td><td>print detail to the console</td></tr>
<tr><th/><td/><td/></tr>
</table>
<br/>
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 222261a8184..0c5dff19f45 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-2023" "version 0.10" "ConTeXt PDF Helpers"
+.TH "mtx-pdf" "1" "01-01-2024" "version 0.10" "ConTeXt PDF Helpers"
.SH NAME
mtx-pdf - ConTeXt PDF Helpers
.SH SYNOPSIS
@@ -17,6 +17,9 @@ show some info about the given file
.B --metadata
show metadata xml blob
.TP
+.B --formdata
+show formdata
+.TP
.B --pretty
replace newlines in metadata
.TP
@@ -24,10 +27,19 @@ replace newlines in metadata
show used fonts (--detail)
.TP
.B --object
-show object"/>
+show object
.TP
.B --links
-show links"/>
+show links
+.TP
+.B --sign
+sign document (assumes signature template)
+.TP
+.B --verify
+verify document
+.TP
+.B --detail
+print detail to the console
.SH AUTHOR
More information about ConTeXt and the tools that come with it can be found at:
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.xml
index 6b2efdcb802..39be43710f6 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.xml
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-pdf.xml
@@ -10,16 +10,23 @@
<subcategory>
<flag name="info"><short>show some info about the given file</short></flag>
<flag name="metadata"><short>show metadata xml blob</short></flag>
+ <flag name="formdata"><short>show formdata</short></flag>
<flag name="pretty"><short>replace newlines in metadata</short></flag>
- <flag name="fonts"><short>show used fonts (<ref name="detail)"/></short></flag>
- <flag name="object"><short>show object"/></short></flag>
- <flag name="links"><short>show links"/></short></flag>
+ <flag name="fonts"><short>show used fonts (<ref name="detail"/>)</short></flag>
+ <flag name="object"><short>show object</short></flag>
+ <flag name="links"><short>show links</short></flag>
+ <flag name="sign"><short>sign document (assumes signature template)</short></flag>
+ <flag name="verify"><short>verify document</short></flag>
+ <flag name="detail"><short>print detail to the console</short></flag>
</subcategory>
<subcategory>
<example><command>mtxrun --script pdf --info foo.pdf</command></example>
<example><command>mtxrun --script pdf --metadata foo.pdf</command></example>
<example><command>mtxrun --script pdf --metadata --pretty foo.pdf</command></example>
<example><command>mtxrun --script pdf --stream=4 foo.pdf</command></example>
+ <example><command>mtxrun --script pdf --sign --certificate=somesign.pem --password=test --uselibrary somefile</command></example>
+ <example><command>mtxrun --script pdf --verify --certificate=somesign.pem --password=test --uselibrary somefile</command></example>
+ <example><command>mtxrun --script pdf --detail=nofpages somefile</command></example>
</subcategory>
</category>
</flags>
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 c1af287c71c..00512ab3cb4 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-2023" "version 1.00" "Plain TeX Runner"
+.TH "mtx-plain" "1" "01-01-2024" "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 13067b503fd..a5b220cd604 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-2023" "version 1.00" "ConTeXt MkIV LuaTeX Profiler"
+.TH "mtx-profile" "1" "01-01-2024" "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 b9e5002354c..8acda886e67 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-2023" "version 0.10" "Rsync Helpers"
+.TH "mtx-rsync" "1" "01-01-2024" "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 3de8ea5876a..c429bf12b56 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-2023" "version 1.00" "Scite Helper Script"
+.TH "mtx-scite" "1" "01-01-2024" "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 5fa9da9cafa..50eea81f111 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-2023" "version 0.10" "Simple Webserver For Helpers"
+.TH "mtx-server" "1" "01-01-2024" "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-spell.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-spell.man
index 578fde17dc2..ffe3850011e 100644
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-spell.man
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-spell.man
@@ -1,4 +1,4 @@
-.TH "mtx-spell" "1" "01-01-2023" "version 0.10" "ConTeXt Word Filtering"
+.TH "mtx-spell" "1" "01-01-2024" "version 0.10" "ConTeXt Word Filtering"
.SH NAME
mtx-spell - ConTeXt Word Filtering
.SH SYNOPSIS
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.html b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.html
new file mode 100644
index 00000000000..504074cae96
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>ConTeXt SyncTeX Checker 1.01</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%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">ConTeXt SyncTeX Checker 1.01 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--edit</th><td></td><td>open file at line: --line=.. --editor=.. sourcefile</td></tr>
+ <tr><th>--list</th><td></td><td>show all areas: synctexfile</td></tr>
+ <tr><th>--goto</th><td></td><td>open file at position: --page=.. --x=.. --y=.. [--tolerance=] --editor=.. synctexfile</td></tr>
+ <tr><th>--report</th><td></td><td>show (tex) file and line: [--direct] --page=.. --x=.. --y=.. [--tolerance=] --console synctexfile</td></tr>
+ <tr><th>--find</th><td></td><td>find (pdf) page and box: [--direct] --file=.. --line=.. synctexfile</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.man b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.man
new file mode 100644
index 00000000000..dae4ab761a1
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.man
@@ -0,0 +1,39 @@
+.TH "mtx-synctex" "1" "01-01-2024" "version 1.01" "SyncTeX Checker"
+.SH NAME
+ mtx-synctex - SyncTeX Checker
+.SH SYNOPSIS
+.B mtxrun --script synctex [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B SyncTeX Checker
+.SH OPTIONS
+.TP
+.B --edit
+open file at line: --line=.. --editor=.. sourcefile
+.TP
+.B --list
+show all areas: synctexfile
+.TP
+.B --goto
+open file at position: --page=.. --x=.. --y=.. [--tolerance=] --editor=.. synctexfile
+.TP
+.B --report
+show (tex) file and line: [--direct] --page=.. --x=.. --y=.. [--tolerance=] --console synctexfile
+.TP
+.B --find
+find (pdf) page and box: [--direct] --file=.. --line=.. synctexfile
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.xml
new file mode 100644
index 00000000000..623090ad5b1
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-synctex.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-synctex</entry>
+ <entry name="detail">SyncTeX Checker</entry>
+ <entry name="version">1.01</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="edit"><short>open file at line: --line=.. --editor=.. sourcefile</short></flag>
+ <flag name="list"><short>show all areas: synctexfile</short></flag>
+ <flag name="goto"><short>open file at position: --page=.. --x=.. --y=.. [--tolerance=] --editor=.. synctexfile</short></flag>
+ <flag name="report"><short>show (tex) file and line: [--direct] --page=.. --x=.. --y=.. [--tolerance=] --console synctexfile</short></flag>
+ <flag name="find"><short>find (pdf) page and box: [--direct] --file=.. --line=.. synctexfile</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
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 0416a11b65d..7ea913aca72 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-2023" "version 1.00" "TeXworks Startup Script"
+.TH "mtx-texworks" "1" "01-01-2024" "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.xml b/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.xml
deleted file mode 100644
index d41322799dd..00000000000
--- a/Master/texmf-dist/doc/context/scripts/mkiv/mtx-timing.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-timing</entry>
- <entry name="detail">ConTeXt Timing Tools</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="xhtml"><short>make xhtml file</short></flag>
- <flag name="launch"><short>launch after conversion</short></flag>
- <flag name="remove"><short>remove after launching</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
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 10751133d80..54f21ddede6 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-2023" "version 1.01" "Some File Related Goodies"
+.TH "mtx-tools" "1" "01-01-2024" "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 651a4c07627..bebbba61e53 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-2023" "version 1.02" "Checker for char-dat.lua"
+.TH "mtx-unicode" "1" "01-01-2024" "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 59725ff8376..7e2c32a06a1 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-2023" "version 0.10" "Simple Unzipper"
+.TH "mtx-unzip" "1" "01-01-2024" "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 83079fb4013..a3398717d4e 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-2023" "version 1.03" "ConTeXt Minimals Updater"
+.TH "mtx-update" "1" "01-01-2024" "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 df9c4f9baaa..f125b36c6af 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-2023" "version 1.00" "vscode extension generator"
+.TH "mtx-vscode" "1" "01-01-2024" "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 8ca17920e66..5049b1f5a89 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-2023" "version 1.00" "ConTeXt Request Watchdog"
+.TH "mtx-watch" "1" "01-01-2024" "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 0f53b233ba4..e54fd1dd32b 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-2023" "version 1.100" "youless Fetcher"
+.TH "mtx-youless" "1" "01-01-2024" "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 644ceefd1e2..29eeb28cc80 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-2023" "version 1.33" "ConTeXt TDS Runner Tool"
+.TH "mtxrun" "1" "01-01-2024" "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/manuals/cld/cld-afewdetails.tex b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-afewdetails.tex
index 9c3221e7528..264861f8c9e 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-afewdetails.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-afewdetails.tex
@@ -187,7 +187,7 @@ context.copy(false,0)
but this works as well:
\startbuffer
-context(node.copy_list(tex.box[0]))
+context(node.copylist(tex.box[0]))
\stopbuffer
\typebuffer
@@ -226,7 +226,7 @@ function userdata.processmystuff(head)
if enabled then
local color = "mynesting:" .. (count % 3)
-- for n in node.traverse(head) do
- for n in node.traverse_id(nodes.nodecodes.glyph,head) do
+ for n in node.traverseid(nodes.nodecodes.glyph,head) do
setcolor(n,color)
end
count = count + 1
@@ -297,7 +297,7 @@ local setcolor = nodes.tracers.colors.set
function userdata.processmystuff(head)
count = count + 1
local color = "mynesting:" .. (count % 3)
- for n in node.traverse_id(nodes.nodecodes.glyph,head) do
+ for n in node.traverseid(nodes.nodecodes.glyph,head) do
setcolor(n,color)
end
return head, true
@@ -340,13 +340,13 @@ The \LUA\ code like similar to the code presented before:
\startbuffer
\startluacode
-local setcolor = nodes.tracers.colors.setlist
-local getmarker = nodes.markers.get
-local hlist_code = nodes.nodecodes.hlist
-local traverse_id = node.traverse_id
+local setcolor = nodes.tracers.colors.setlist
+local getmarker = nodes.markers.get
+local hlist_code = nodes.nodecodes.hlist
+local traverseid = node.traverseid
function userdata.processmystuff(head)
- for n in traverse_id(hlist_code,head) do
+ for n in traverseid(hlist_code,head) do
local m = getmarker(n,"mymarker")
if m then
setcolor(n.list,"mymarker:" .. m)
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-nicetoknow.tex b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-nicetoknow.tex
index 950e394c7c0..cd5b985879d 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-nicetoknow.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/cld/cld-nicetoknow.tex
@@ -105,7 +105,7 @@ tex.setbox(0,b)
So we end up with:
\starttyping
-local b = node.copy_list(tex.getbox(0))
+local b = node.copylist(tex.getbox(0))
-- mess around with b
tex.setbox(0,b)
\stoptyping
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/colors/colors-graphics.tex b/Master/texmf-dist/doc/context/sources/general/manuals/colors/colors-graphics.tex
index c438a4630cc..78319d5ad4f 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/colors/colors-graphics.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/colors/colors-graphics.tex
@@ -1,3 +1,4 @@
+
% language=us runpath=texruns:manuals/colors
\startcomponent colors-basics
@@ -229,6 +230,185 @@ on bad images).
\stopsection
+\startsection[title=Masks]
+
+A \PNG\ bitmap image can have a mask that permits a background to shine through
+but you can also apply that effect to a regular \PNG\ image. The next examples
+use two (pre)defined masks:
+
+\startbuffer
+\registerfiguremask [mymask1] {
+ {
+ { 0, 100, 0x00 },
+ { 101, 200, 0x7F },
+ { 201, 255, 0xFF },
+ }
+}
+
+\registerfiguremask [mymask2] {
+ 210
+}
+\stopbuffer
+
+% demomask = {
+% { 0, 63, 0 },
+% { 64, 127, 127 },
+% { 128, 195, 195 },
+% { 196, 255, 255 },
+% }
+
+% \registerfiguremask [mymask1] {
+% function()
+% return {
+% { 0, 100, 0x00 },
+% { 101, 200, 0x7F },
+% { 201, 255, 0xFF },
+% }
+% end
+% }
+
+\typebuffer
+
+The first mask maps the (grayscale) image values onto a mask value by range while
+the second just passes a criterium. The argument to \type {\registerfiguremask}
+is a number, table or string in \LUA\ speak
+
+\getbuffer
+
+For the examples we define two colors:
+
+\startbuffer
+\definecolor[mymaskcolor1][darkred]
+\definecolor[mymaskcolor2][.75(darkblue,white)]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\startbuffer[zero]
+\externalfigure
+ [2019-sneaky-bw-lowres.png]
+ [width=\measure{combination}]
+\stopbuffer
+
+\startbuffer[one]
+\externalfigure
+ [2019-sneaky-bw-lowres.png]
+ [background=color,
+ backgroundcolor=mymaskcolor1,
+ mask=mymask1,
+ width=\measure{combination}]
+\stopbuffer
+
+\startbuffer[two]
+\externalfigure
+ [2019-sneaky-bw-lowres.png]
+ [background=color,
+ backgroundcolor=mymaskcolor2,
+ mask=mymask2,
+ width=\measure{combination}]
+\stopbuffer
+
+\startbuffer[three]
+\externalfigure
+ [2019-sneaky-bw-lowres.png]
+ [background=color,
+ backgroundcolor=mymaskcolor2,
+ mask=demomask,
+ width=\measure{combination}]
+\stopbuffer
+
+We now include two images:
+
+\typebuffer[one]
+
+and
+
+\typebuffer[two]
+
+The result is shown in \in {figure} [fig:masks:one] and shows that one has
+probably experiment a bit with the values. The first shows the original and the
+last the predefined \quote {demomask} that uses a table with four ranges.
+
+\startplacefigure[title=Masks,reference=fig:masks:one]
+ \startcombination[4*1]
+ {\inlinebuffer[zero]} {original}
+ {\inlinebuffer[one]} {table}
+ {\inlinebuffer[two]} {number}
+ {\inlinebuffer[three]}{demomask}
+ \stopcombination
+\stopplacefigure
+
+We can also use an image as mask. Take these three definitions:
+
+\startbuffer[one]
+\externalfigure
+ [mill.png]
+ [height=5cm]
+\stopbuffer
+
+\startbuffer[two]
+\externalfigure
+ [2019-sneaky-bw-lowres.png]
+ [height=5cm]
+\stopbuffer
+
+\startbuffer[three]
+\externalfigure
+ [mill.png]
+ [mask=2019-sneaky-bw-lowres.png,height=5cm]
+\stopbuffer
+
+\typebuffer[one,two,three]
+
+In \in {figure} [fig:masks:two] the third example has both images stacked.
+
+\startplacefigure[title=Masks,reference=fig:masks:two]
+ \startcombination[3*1]
+ {\inlinebuffer[one]} {}
+ {\inlinebuffer[two]} {}
+ {\inlinebuffer[three]}{}
+ \stopcombination
+\stopplacefigure
+
+Next we show how to make an image lighter or darker. For this we use the \type
+{range} key. It can be assigned a number (fraction) or a name that serves as
+lookup in a registry. As with masks these are \LUA\ definitions. AN example of a
+range definition is:
+
+\startbuffer
+\registerfigurerange [myrange] {
+ { 0.2, 1.2 }
+}
+\stopbuffer
+
+For an \RGB\ you can provide two or six values. In \in {figure} [fig:ranges:gray]
+we show a lighter, normal, darker and limited example. In \in {figure}
+[fig:ranges:color] we apply them to a \JPEG\ image.
+
+\typebuffer \getbuffer
+
+\startplacefigure[title=Ranges,reference=fig:ranges:gray]
+ \startcombination[4*1]
+ {\externalfigure[mill.png][width=\measure{combination},range=0.80]} {\type{range=0.80}}
+ {\externalfigure[mill.png][width=\measure{combination}]} {default}
+ {\externalfigure[mill.png][width=\measure{combination},range=1.20]} {\type{range=1.20}}
+ {\externalfigure[mill.png][width=\measure{combination},range=myrange]} {\type{range=myrange}}
+ \stopcombination
+\stopplacefigure
+
+\startplacefigure[title=Ranges,reference=fig:ranges:color]
+ \startcombination[4*1]
+ {\externalfigure[hacker.jpg][width=\measure{combination},range=0.80]} {\type{range=0.80}}
+ {\externalfigure[hacker.jpg][width=\measure{combination}]} {default}
+ {\externalfigure[hacker.jpg][width=\measure{combination},range=1.20]} {\type{range=1.20}}
+ {\externalfigure[hacker.jpg][width=\measure{combination},range=myrange]} {\type{range=myrange}}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-compact.tex b/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-compact.tex
new file mode 100644
index 00000000000..69cfdfb55b9
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-compact.tex
@@ -0,0 +1,517 @@
+
+% language=us runpath=texruns:manuals/fonts
+
+\continuewhenlmtxmode
+
+\startcomponent fonts-compact
+
+\environment fonts-environment
+
+\definetypeface
+ [narrowtt] [tt]
+ [mono] [modern-condensed] [default] [features=none]
+
+\startchapter[title=Compact][color=darkgray]
+
+\startsection[title=Introduction]
+
+The title of this chapter is somewhat misleading but in the end a lot boils down
+to efficient but flexible usage as offered in \CONTEXT\ \LMTX\ and \LUAMETATEX.
+This also means that what is discussed here does not apply to \MKIV.
+
+\stopsection
+
+\startsection[title=Compact mode]
+
+\startsubsection[title=What \TEX\ needs]
+
+A traditional \TEX\ approach to fonts is that you explicitly load a font
+that then gets an identifier which is used to trigger its usage. In plain \TEX\
+you find these lines:
+
+\startcolumns[n=3]
+\starttyping
+\font\tenrm cmr10
+\font\preloaded cmr9
+\font\preloaded cmr8
+\font\sevenrm cmr7
+\font\preloaded cmr6
+\font\fiverm cmr5
+
+\font\teni cmmi10
+\font\preloaded cmmi9
+\font\preloaded cmmi8
+\font\seveni cmmi7
+\font\preloaded cmmi6
+\font\fivei cmmi5
+
+\font\tensy cmsy10
+\font\preloaded cmsy9
+\font\preloaded cmsy8
+\font\sevensy cmsy7
+\font\preloaded cmsy6
+\font\fivesy cmsy5
+
+\font\tenex cmex10
+
+\font\preloaded cmss10
+\font\preloaded cmssq8
+
+\font\preloaded cmssi10
+\font\preloaded cmssqi8
+
+\font\tenbf cmbx10
+\font\preloaded cmbx9
+\font\preloaded cmbx8
+\font\sevenbf cmbx7
+\font\preloaded cmbx6
+\font\fivebf cmbx5
+
+\font\tentt cmtt10
+\font\preloaded cmtt9
+\font\preloaded cmtt8
+
+\font\preloaded cmsltt10
+
+\font\tensl cmsl10
+\font\preloaded cmsl9
+\font\preloaded cmsl8
+
+\font\tenit cmti10
+\font\preloaded cmti9
+\font\preloaded cmti8
+\font\preloaded cmti7
+\stoptyping
+\stopcolumns
+
+There are a few more later on in that file. Although users seldom see such low
+level definitions it shows a few interesting aspects. First of all, we see that
+there are different fonts for different sizes. These can be triggered with
+commands like \type {\tenbf}. We also see that some fonts get the name \type
+{\preloaded} but because later one we have:
+
+\starttyping
+\let\preloaded\undefined
+\stoptyping
+
+that command is no longer meaningful. The fonts are loaded but not accessible.
+However, when you define it again, the already loaded variant will be used which
+might save some runtime. Back to the sizes: all is centered around a ten point
+body font. The smaller sizes are for math and footnotes, the larger ones for
+section titles and such. The different sizes are optimized for that size and
+expected to be printed at that size. Of course looking at a document on a phone,
+epub device, high resolution monitor or beamer image, spoils that concept:
+instead of being optimized for some size it then becomes a variant with different
+properties. A seven point glyph at indeed seven point in a math superscript makes
+sense but when blown up to 16 point there is less need for a different shape
+unless one wants (for instance) to run the scripts narrower. The danger of ink
+filling shapes at small sizes is not present when we scale up.
+
+Anyway, the engine loads a font and when triggered it will use the dimensions
+that it provides: character properties like widths, heights, depths, italic
+corrections, kerns, ligatures, math variants and extensibles as well as font
+properties like spacing. If you load a ten point font at fifteen point the
+original gets scaled and a copy is used with these new properties. If you use
+400 sizes, you get 400 copies.
+
+\stopsubsection
+
+\startsubsection[title=How \LUATEX\ works]
+
+Because \LUATEX\ is a wide engine loading a font not only takes more time but
+using one also consumes more memory. In principle there should be no real
+difference in the amount of fonts loaded unless the macro package does a poor
+job. In what we call base mode, there is no difference with the traditional
+approach: \TEX\ needs the usual properties so, assuming that callbacks are used
+for font management, only these have to be passed to the engine. In what we call
+node mode in \CONTEXT\ rendering is delegated to \LUA. The engine is not involved
+in for instance ligature building and kerning.
+
+Where in a traditional engine small caps and old style variants are bound to
+specific fonts, using them involves loading a new instance. However, in \CONTEXT\
+we can avoid that by using dynamic features. This dynamic mechanism is part of
+node mode and is a convenient way to deal with small caps and oldstyle shapes. So
+here we can actually save some memory due to less instances but of course at the
+cost of some more complexity. But we still have dedicated instances for say eight
+point and ten point.
+
+\stopsubsection
+
+\startsubsection[title=What \LUAMETATEX\ can do]
+
+In this engine we can do scaling of glyphs on demand. This makes it possible to
+only define a ten point instance and scale for instance an eight point size from
+that instance. This can come at the cost of more runtime due to more calculations
+but in the end experiments demonstrated that runtime can become less. Memory
+consumption of course is less anyway.
+
+This scaling feature has quite some impact on the front|-|end because dimensions
+that relate to the current font might have to be scaled too. It is definitely
+something to take into account at the \LUA\ end. In addition to scaling we also
+have some other manipulations. Although these are taken into account in the
+frontend, it is the backend that eventually has to take care of it.
+
+\starttabulate
+\NC \type {\glyphscale } \NC scales the glyphs in two directions \NC \NR
+\NC \type {\glyphxscale} \NC scales the glyphs horizontally, aka extending \NC \NR
+\NC \type {\glyphyscale} \NC scales the glyphs vertically, aka squeezing \NC \NR
+\NC \type {\glyphslant } \NC transforms the glyphs such that it becomes oblique\NC \NR
+\NC \type {\glyphweight} \NC boldens the glyphs \NC \NR
+\stoptabulate
+
+Apart from slanting all these primitives result in different metrics. The weight is
+somewhat tricky because here we need some guesswork.
+
+When we use compact font mode in \CONTEXT\ \LMTX, the same font is loaded once
+and scaled on demand using the above control options. Of course this need some
+management, for instance because when setting the scale an already active scale
+might effectively get rescaled.
+
+% \unprotect
+% \meaning\font_scale_defined_x
+% \protect
+% \glyphscale\dimexpr\xtextface*\plushundred/\onepoint\relax
+% \gyphrescale\xtextface\relax
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title=Design sizes]
+
+\startsubsection[title=Introduction]
+
+The first \TEX\ distributions had an important characteristic: the fonts that
+came with them were tuned for a certain size and we could speak of them having
+\quote {design sizes}. There were good reasons for this.
+
+\startitemize
+
+\startitem
+ The typeset result was supposed to be printed and we were not talking desktop
+ printers here, but printing presses. A book normally came in a ten point
+ design; after all, how many type does a typesetter has available in lead or
+ film.
+\stopitem
+
+\startitem
+ When math is involved there are two levels of script which means that there
+ are seven and five point sizes used too. At these smaller sizes some details of a
+ glyph have to be exaggerated and other bits and pieces have to become more
+ open in order not to become a blob of black ink.
+\stopitem
+
+\startitem
+ A section header or maybe a bit larger chapter title got its own size, often a
+ bit heavier and maybe running somewhat wider.
+\stopitem
+
+\startitem
+ Combined, this kind of usage results in a predictable way of presenting the
+ result to the user. Unless the reader uses a magnifying glass, what you see is
+ what you got.
+\stopitem
+
+\stopitemize
+
+Compare this to todays rendering and presentation. What is a ten point on a
+mobile phone, 1920x1080 14 inch laptop screen, a 27 inch 4K desktop monitor, or
+beamed on the wall presentation with a 3 meter diameter? And let's not bring
+these low res epub devices into the discussion. It is of course also a matter of
+taste but it is not uncommon to hear \TEX ies claim virtues of fonts and the
+rendering with \TEX\ (take expansion) while at the same time observing that they
+ignore aspects of typesetting that would really make their documents look nice.
+
+Where in the good old \TEX\ approach, rooted in traditional typesetting and
+printing, the concept of \quote {design size} made sense, I personally think that
+in today's rendering and usage it has no real meaning. A basic ten point font can
+show up in any size and is not adapted on-the-fly which in turn would demand
+on-the-fly typesetting with definitely a different look and feel due to different
+line breaks, and we don't even consider how scaling (bitmap or vector) images fit
+into such adaptations. It might work in browsers but not on more traditional
+designed and optimized published content.
+
+There is a sort of tradition that a font comes in \quote {normal}, \quote {bold},
+\quote {italic} and \quote {bolditalic} shapes. It can make sense to come up with
+a bit lighter and more heavy variant, but some designers can't make up their mind
+and come with a whole range, so we see \quote {thin}, \quote {demi-bold}, \quote
+{medium} and \quote {medium-bold}, and whatever fits the repertoire. The choice
+of what looks best is delegated to the user. In the past there definitely was a
+commercial aspect to this, after all each set has to be bought, and when it's not
+clear what to use you end up with dozens of fonts, of which most are never used.
+Today the drive probably comes from the possibilities that font design programs
+offer. And when variable fonts showed up we suddenly saw fonts come in many
+weights, again putting the burden of what looks best on users instead of what is
+intended on designers. As a side effect, the distinction between designs becomes
+vague and there is a danger that in the end users no longer really care what font
+they use because they can make it look like any other anyway.
+
+I like to argue that these \quote {new} fonts that come in what some call design
+sizes has little to do with design sizes in the traditional sense. The variants
+more reflect usage, like \quote {display} or \quote {heading}. As mentioned
+above, one can indeed consider them to be designed for (say) larger than default
+sizes, but then the word \quote {size} no longer hold.
+
+Say that in a traditional \TEX\ document one has the running text in ten point. A
+section header can use the twelve point and a chapter heading fourteen (\TEX\ has
+these 14.4pt, 17.3pt sizes). In print they really are like that but but when
+watched on a device the ten point can effectively be a eight point (epub) or
+twenty point (monitor) so there size has become meaningless because the font is
+not seen at the size it was designed for. When we choose a different one (say
+\quote {display}) we do so because of other properties than size. This means that
+instead of \quote {design size} we can better talk of \quote {usage}.
+
+The advantage of talking \quote {usage} is that we don't need to think size. In a
+traditional \TEX\ setup using design sizes you end up with (difficult) choices.
+If the document is in eleven point, do we scale down the twelve point or scale up
+the ten point, assuming that we have ten and twelve point designs optimized for
+the running text. And how about math when we go down to eight point in footnotes,
+do we really use five point script and three point script script or do we go for
+six point and five or maybe four point. Nowadays we can decide to just scale
+relative, and sticking to what was common in the days of lead typesetters with
+fixed sizes is not needed. Maybe a gradual evolution meant that we stuck to
+concepts a bit too much. So in todays \TEX\ setup we can decide to just define a
+basic setup (no design sizes at all) and do that multiple times depending on
+usage: kicking in a different set of shapes for \quote {display} and \quote
+{heading} when available. There is no reason to use a shape meant for display for
+a sixteen point running text because we scale the ten point and then use the
+display font at (say) twenty four point: it is usage and not scale that matters
+here. And an occasional ten point display font used at ten point in a ten point
+running text can have some use, but we make sure to trigger it with the right
+denomination: we mix a \quote {display} design into a \quote {regular} stream at
+the same size.
+
+It is of course also a matter of perception and taste but as with font expansion
+(aka hz) it could be annoying to see two different two's in $2^2$, something at
+10 points might look better at small sizes but worse as larger. In {figures}
+[fig:designsizes:1] \in {and} [fig:designsizes:2] you can see how it looks when
+we scale a design size beyond its intended size. Especially the second stylistic
+variant (meant for script script) can stand out.
+
+\def\SampleOne#1#2{\switchtobodyfont[#1]\scale[scale=#2000]{\im{2^{2^2}}}}
+
+\startbuffer
+\startcombination[6*3]
+ {\SampleOne{lucida} {1}} {}
+ {\SampleOne{lucida} {2}} {}
+ {\SampleOne{lucida} {3}} {}
+ {\SampleOne{lucida} {4}} {}
+ {\SampleOne{lucida} {5}} {}
+ {\SampleOne{lucida} {6}} {}
+ {\SampleOne{pagella}{1}} {}
+ {\SampleOne{pagella}{2}} {}
+ {\SampleOne{pagella}{3}} {}
+ {\SampleOne{pagella}{4}} {}
+ {\SampleOne{pagella}{5}} {}
+ {\SampleOne{pagella}{6}} {}
+ {\SampleOne{modern} {1}} {}
+ {\SampleOne{modern} {2}} {}
+ {\SampleOne{modern} {3}} {}
+ {\SampleOne{modern} {4}} {}
+ {\SampleOne{modern} {5}} {}
+ {\SampleOne{modern} {6}} {}
+\stopcombination
+\stopbuffer
+
+\startplacefigure[title={Design sizes beyond their design size (1).},reference=fig:designsizes:1]
+ \getbuffer
+\stopplacefigure
+
+\def\SampleOne#1#2{\switchtobodyfont[#1]\scale[scale=#2000]{\im{2\char\getmathcharone`2 \char\getmathchartwo`2}}}
+
+\startplacefigure[title={Design sizes beyond their design size (2).},reference=fig:designsizes:2]
+ \getbuffer
+\stopplacefigure
+
+With arbitrary scaling \quote {design size} no longer is a meaningful concept but
+(intended) usage might be; we could just drop the \quote {sizes} and stick to
+\quote {design} or maybe go for \quote {design variants} or simply \quote
+{usage}. So, that is what in \CONTEXT\ we will carry on. That still leaves the
+user the horrible task of figuring out all these weights, because in the worst
+case all the usage sets (3-5) combined with weights (3-8) will give us (9-40)
+setups to come up with and then choose from. Of course we can decide that the
+regular shape is what the designer came up with and that the rest is just
+marketing and bit of technical show-off. And if it's all too much work for a
+user, the regular shapes a good choice anyway. I wonder if readers really care
+that much, especially when they read on devices instead of proper high resolution
+print.
+
+\stopsubsection
+
+\startsubsection[title=A system]
+
+Mainly because, as shown above, \TEX\ shipped with Computer Modern in several
+design sizes the low level font system is designed to deal with that. This means
+that setups for \MKII\ look more complex than those for \MKIV\ and \LMTX,
+although deep down the same mechanism is active.
+
+Most fonts come with normal, bold, italic and bolditalic variants and for such a
+basic set of four, defining a typescript is relatively easy. If we don't need to
+access the specific fonts by name (like \typ {MyFontSerif}) we can just map
+(file)names onto \type {Serif} directly. If the \quote {select font} mechanism is
+used (\typ {\definefontfamily}) one doesn't even make typescripts but that
+assumes that we can reliably resolve fontnames.
+
+So how, in the perspective of the mentioned (usage specific) font variants does
+one set up a system. I will use Iwona as an example because that font comes in
+different variants. For that font we have the following choices:
+
+\startlines
+iwona iwona-light iwona-medium iwona-heavy
+iwona-cond iwona-light-cond iwona-medium-cond iwona-heavy-cond
+\stoplines
+
+\startbuffer[iwona-use]
+\usebodyfont[iwona]
+\usebodyfont[iwona-heavy]
+\usebodyfont[iwona-cond]
+\stopbuffer
+
+Say that we know that we use, we can instruct \CONTEXT\ to preload these so that
+we don't get local definitions and loading when we use one of them grouped, as in
+a section title.
+
+\typebuffer[iwona-use]
+
+These names are a bit too bound to the fontname so we introduce some abstraction:
+
+\startbuffer[iwona-abstract]
+\aliasbodyfont[mainfont] [iwona]
+\aliasbodyfont[titlefont][iwona-heavy]
+\aliasbodyfont[notefont] [iwona-cond]
+\stopbuffer
+
+\typebuffer[iwona-abstract]
+
+\startbuffer[iwona-demo]
+\setupbodyfont[mainfont]
+\setuphead[chapter][style=\switchtobodyfont[titlefont]\tfd]
+\setuphead[section][style=\switchtobodyfont[titlefont]\tfc]
+\setupnotes[bodyfont={notefont,small}]
+
+\starttext
+
+\startchapter[title=Demo]
+\startsection[title=Demo]
+\samplefile {tufte} \footnote{\samplefile{tufte}}
+\stopsection
+\stopchapter
+
+\stoptext
+\stopbuffer
+
+\typebuffer[iwona-demo]
+
+We see the result in \in {figure} [fig:iwona:demo] and when that example is
+processed the log tells that quite some fonts got loaded: 18. The majority is
+traditional math fonts that get assembled into a pseudo \OPENTYPE\ font.
+
+\startplacefigure[default=page,title={An example font setup},reference=fig:iwona:demo]
+ \scale[width=\textwidth]{\typesetbuffer[iwona-use,iwona-abstract,iwona-demo]}
+\stopplacefigure
+
+The log also mentions: {\tt 28 instances, 24 shared in backend, 2 common vectors,
+22 common hashes, load time 0.615 seconds}. When we start the document with:
+
+\starttyping
+\enableexperiments[fonts.compact]
+\stoptyping
+
+We can see that less instances are loaded: {\tt 6 instances, 2 shared in backend,
+2 common vectors, 0 common hashes, load time 0.154 seconds}. We also save half a
+second. All this is because we now enabled scaling on-the-fly.
+
+\stopsubsection
+
+\startsubsection[title=Relations]
+
+There is a lot of history behind the font system. We started out with design
+sizes and features distributed over fonts. So, at the lowest level we had to
+handle for instance small caps and oldstyle via specific definitions. A tenpoint
+definition looked similar to a twelvepoint but with different font names. On top
+of that there were more general (and abstract) definitions as well as size
+specific mappings to larger or smaller variants of the fonts used at that size.
+
+With a single design size a setup is much simpler but it still uses that granular
+low level mechanism. In all of this, typescripts play an important role: they are
+recipes that relate symbolic names to files, and use these symbolic names in
+assemblies of fonts. Eventually a combination of serif, sans, mono and math is
+defined, even if most fonts don't have these four available. In that case we
+combine different designs.
+
+We could come up with a new system and it could even be a bit faster but we also
+need to keep compatibility in mind. It is not trivial to come up with something
+better (read: more \LMTX-ish) that is backward compatible. The default setup for
+a bodyfont is a rather safe one but not always the best for every body font.
+Without complicatign the existing mechanisms too much some extensions in for
+instance the bodyfont environment system were possible, for instance:
+
+% \setupbodyfontenvironment
+% [metric]
+% [
+% small=0.7,
+% interlinespace=1.4,
+% ]
+
+\starttyping
+\definebodyfontenvironment[iwona] [default][metric]
+\definebodyfontenvironment[iwona-heavy][default][metric]
+\definebodyfontenvironment[iwona-cond] [default][metric]
+\stoptyping
+
+where \type {metric} is a predefined setup and \type {default} indicates that all
+unset sizes use that one. You can define your own or adapt the predefined ones.
+
+\starttyping
+\setupbodyfontenvironment
+ [metric]
+ [small=0.7]
+\stoptyping
+
+or
+
+\starttyping
+\setupbodyfontenvironment
+ [metric]
+ [interlinespace=1.4]
+\stoptyping
+
+for a line height relative to the bodyfont size. Although this seldom happens
+you can be even mor granular. Say that you have
+
+\starttyping
+\definetypeface [DejavuA] [rm] [serif] [dejavu] [default]
+\definetypeface [DejavuA] [ss] [sans] [dejavu] [default]
+\definetypeface [DejavuA] [tt] [mono] [dejavu] [default]
+\definetypeface [DejavuA] [mm] [math] [dejavu] [default]
+\stoptyping
+
+We can now make the sans a bit smaller:
+
+\starttyping
+\definebodyfontenvironment
+ [DejavuA] [ss] [default]
+ [text=0.95, ...]
+\stoptyping
+
+and a specific bodyfont size even more:
+
+\starttyping
+\definebodyfontenvironment
+ [DejavuA] [ss] [8pt]
+ [text=0.85, ...]
+\stoptyping
+
+Of course this kind of setups can best be achieved with an isolated, stepwise
+written environment file because testing it on a huge and versatile document
+source is not much fun.
+
+\stopsubsection
+
+% TODO: set tx to be some other bodyfont but with same interlinespace
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-introduction.tex b/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-introduction.tex
index d0e844d1f0c..010fd079ae7 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-introduction.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-introduction.tex
@@ -93,3 +93,22 @@ Summer 2011 \endash\ Spring 2016
\stopchapter
\stopcomponent
+
+% When visiting one of our small town supermarkets I often observe how well suited
+% these are for kids to explore their abilities due to the partime jobs they offer:
+% human interaction, problem solving, calculus, working together, taking
+% initiatives come to mind. It is therefore in my opinion one these cases where
+% further automation (like self scan counters) is going to backfire on society.
+% These micro societies with various tasks to perform are perfect low risk learning
+% environments.
+
+% In a similar fashion one can observe the way fonts are used in documents. It is
+% all about making choices, setting up a consistent system, suitability to the task
+% and kind of document, not going overboard in features, sizes, variants and more.
+% One might need to improvise and compromise. It is a good learning environment.
+% One can argue that the more we automate the less opportunity there is for users
+% to explore.
+
+% That said, a \TEX\ ecosystem has to provide some tools to make it possible to set
+% up fonts, and can best hide some nasty (and messy) details, but at the same time
+% has to provide enough flexibility to explore and educate.
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-math.tex b/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-math.tex
index 745a5e9cb6a..e69612d5521 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-math.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-math.tex
@@ -276,6 +276,8 @@ glyphs and building special constructs. The same is true for spacing. Although
math fonts do have kerning information, most of the math spacing is controlled
by properties of characters and not by the font.
+\startmkivmode
+
\unexpanded\def\SampleLine#1%
{\NC
\type{$a #1{+} b$}
@@ -299,6 +301,8 @@ according to their usage. \footnote {There are a few more commands, like \type
{\mathlimop}, \type {\mathnolop} and \type {mathbox} but these are used
differently.}
+\stopmkivmode
+
With \TEX\ being the oldest and still dominant math renderer it is no surprise
that \MICROSOFT\ modelled its math renderer after \TEX\ and Cambria quite well
suits the concept. In retrospect it is somewhat unfortunate that we're still
@@ -776,12 +780,12 @@ command. An example is the fence mechanism:
\definemathfence
[fancybracket] [bracket]
[color=darkblue]
-\definemathfence
+\definemathfence % mkiv: command, mkxl: define
[smallbracket] [bracket]
- [command=yes,color=darkgreen,mathstyle=small]
-\definemathfence
+ [command=yes,define=yes,color=darkgreen,mathstyle=small]
+\definemathfence % mkiv: command, mkxl: define
[normalbracket] [bracket]
- [command=yes,color=darkred]
+ [command=yes,define=yes,color=darkred]
\stopbuffer
\typebuffer \getbuffer
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-mkiv.tex
index 79d9535741f..21b9c6ce597 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/fonts/fonts-mkiv.tex
@@ -67,6 +67,7 @@
\component fonts-extensions
\component fonts-hooks
\component fonts-tricks
+ \component fonts-compact
\stopbodymatter
\startappendices
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/graphics/graphics.tex b/Master/texmf-dist/doc/context/sources/general/manuals/graphics/graphics.tex
index 97785c1700b..92a225d2689 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/graphics/graphics.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/graphics/graphics.tex
@@ -52,8 +52,8 @@
-- kind of self-explaining:
- local xsize = 210
- local ysize = 297
+ local xsize = 255
+ local ysize = 255
local colordepth = 1
local usemask = true
local colorspace = "rgb"
@@ -73,7 +73,7 @@
local d = data[i]
local m = mask[i]
for j=1,xsize do
- d[j] = { i, max(i,j), j, min(i,j) }
+ d[j] = { i, max(i,j), min(i,j) }
m[j] = random(minmask,maxmask)
end
end
@@ -147,8 +147,8 @@ become a linked list of so called nodes: glyphs, kerns, glue, rules, boxes and a
couple of more items. But, when doing the job, \TEX\ is only interested in
dimensions.
-In traditional \TEX\ an image inclusion happens via the extension primitive
-\type {\special}, so you can think of something:
+In traditional \TEX\ an image inclusion happens via the extension primitive \type
+{\special}, so you can think of something:
\starttyping
\vbox to 10cm {%
@@ -389,10 +389,10 @@ The actually inclusion of this image happened with:
% point but for now you need to enable that explicitly:
%
% \starttyping[option=TEX]
-% \enabledirectrive[graphics.pdf.uselua]
-% \enabledirectrive[graphics.jpg.uselua]
-% \enabledirectrive[graphics.jp2.uselua]
-% \enabledirectrive[graphics.png.uselua]
+% \enabledirective[graphics.pdf.uselua]
+% \enabledirective[graphics.jpg.uselua]
+% \enabledirective[graphics.jp2.uselua]
+% \enabledirective[graphics.png.uselua]
% \stoptyping
%
% All four can be enabled with:
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-accuracy.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-accuracy.tex
new file mode 100644
index 00000000000..9247de48377
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-accuracy.tex
@@ -0,0 +1,335 @@
+% language=us runpath=texruns:manuals/lowlevel
+
+\environment lowlevel-style
+
+\startdocument
+ [title=accuracy,
+ color=darkgray]
+
+\startsectionlevel[title=Introduction]
+
+When you look at \TEX\ and \METAPOST\ output the accuracy of the rendering stands
+out, unless of course you do a sloppy job on design and interfere badly with the
+system. Much has to do with the fact that calculations are very precise,
+especially given the time when \TEX\ was written. Because \TEX\ doesn't rely on
+(at that time non|-|portable) floating point calculations, it does all with 32
+bit integers, except in the backend where glue calculations are used for
+finalizing the glue values. It all changed a bit when we added \LUA\ because
+there we mix integers and doubles but in practice it works out okay.
+
+When looking at floating point (and posits) one can end up in discussions about
+which one is better, what the flaws fo each are, etc. Here we're only interested
+in the fact that posits are more accurate in the ranges where \TEX\ and
+\METAPOST\ operate, as well as the fact that we only have 32 bits for floats in
+\TEX, unless we patch more heavily. So, it is also very much about storage.
+
+When you work with dimensions like points, they get converted to an integer
+number (the \type {sp} unit) and from that it's just integer calculations. The
+maximum dimension is \the\maxdimen, which already shows a rounding issue. Of
+course when one goes precise for sure there is some loss, but on the average
+we're okay. So, in the next example the two last rows are equivalent:
+
+\starttabulate[|Tr|r|r|]
+\NC .1pt \NC \the\dimexpr.1pt \relax \NC \number\dimexpr.1pt \relax sp \NC \NR
+\NC .2pt \NC \the\dimexpr.2pt \relax \NC \number\dimexpr.2pt \relax sp \NC \NR
+\NC .3pt \NC \the\dimexpr.3pt \relax \NC \number\dimexpr.3pt \relax sp \NC \NR
+\NC .1pt + .2pt \NC \the\dimexpr.1pt+.2pt\relax \NC \number\dimexpr.1pt+.2pt\relax sp \NC \NR
+\stoptabulate
+
+When we're at the \LUA\ end things are different, there numbers are mapped onto
+64 bit floating point variables (doubles) and not all numbers map well. This is
+what we get when we work with doubles in \LUA:
+
+\starttabulate[|Tr|r|]
+\NC .1 \NC \luaexpr{.1 } \NC \NR
+\NC .2 \NC \luaexpr{.2 } \NC \NR
+\NC .3 \NC \luaexpr{.3 } \NC \NR
+\NC .1 + .2 \NC \luaexpr{.1+.2} \NC \NR
+\stoptabulate
+
+The serialization looks as if all is okay but when we test for equality there
+is a problem:
+
+\starttabulate[|Tr|l|]
+\NC .3 == .3 \NC \luaexpr{tostring( .3 == .3)} \NC \NR
+\NC .1 + .2 == .3 \NC \luaexpr{tostring(.1 + .2 == .3)} \NC \NR
+\stoptabulate
+
+This means that a test like this can give false positives or negatives unless one
+tests the difference against the accuracy (in \METAPOST\ we have the {eps}
+variable for that). In \TEX\ clipping of the decimal fraction influences equality.
+
+\starttabulate[|Tr|l|]
+\NC \type{\iflua { .3 == .3 } Y\else N\fi} \NC \iflua{ .3 == .3} equal\else different\fi \NC \NR
+\NC \type{\iflua { .1 + .2 == .3 } Y\else N\fi} \NC \iflua{.1 + .2 == .3} equal\else different\fi \NC \NR
+\stoptabulate
+
+The serialization above misguides us because the number of digits displayed is
+limited. Actually, when we would compare serialized strings the equality holds,
+definitely within the accuracy of \TEX. But here is reality:
+
+\startluacode
+ local a = 0.1
+ local b = 0.2
+ local c = 0.3
+ local d = a + b
+ local NC, NR = context.NC, context.NR
+ local function show(f)
+ context.NC() context(context.escaped(f))
+ context.NC() context(f,c)
+ context.NC() context(f,d)
+ context.NC() context.NR()
+ end
+ context.starttabulate { "|T|l|l|" }
+ context.NC()
+ context.NC() context(".3")
+ context.NC() context(".1 + .2")
+ context.NC() context.NR()
+ -- show("%0.05g",c)
+ show("%0.10g",c)
+ show("%0.17g",c)
+ show("%0.20g",c)
+ show("%0.25g",c)
+ context.stoptabulate()
+\stopluacode
+
+The above examples use $0.1$, $0.2$ and $0.3$ and on a 32 bit float that actually
+works out okay, but \LUAMETATEX\ is 64 bit. Is this really important in practice?
+There are indeed cases where we are bitten by this. At the \LUA\ end we seldom
+test for equality on calculated values but it might impact check for less or
+greater then. At the \TEX\ end there are a few cases where we have issues but
+these also relate to the limited precision. It is not uncommon to loose a few
+scaled points so that has to be taken into account then. So how can we deal with
+this? In the next section(s) an alternative approach is discussed. It is not so
+much the solution for all problems but who knows.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Posits]
+
+% TODO: don't check for sign (1+2)
+
+The next table shows the same as what we started with but with a different
+serialization.
+
+\starttabulate[|Tr|r|]
+\NC .1 \NC \positunum{.1 } \NC \NR
+\NC .2 \NC \positunum{.2 } \NC \NR
+\NC .3 \NC \positunum{.3 } \NC \NR
+\NC .1 + .2 \NC \positunum{.1 + .2} \NC \NR
+\stoptabulate
+
+And here we get equality in both cases:
+
+\starttabulate[|Tr|l|]
+\NC .3 == .3 \NC \positunum{ .3 == .3} \NC \NR
+\NC .1 + .2 == .3 \NC \positunum{.1 + .2 == .3} \NC \NR
+\stoptabulate
+
+The next table shows what we actually are dealing with. The \type {\if}|-|test is
+not a primitive but provided by \CONTEXT.
+
+\starttabulate[|Tr|l|]
+\NC \type{\ifpositunum { .3 == .3 } Y\else N\fi} \NC \ifpositunum{ .3 == .3} equal\else different\fi \NC \NR
+\NC \type{\ifpositunum { .1 + .2 == .3 } Y\else N\fi} \NC \ifpositunum{.1 + .2 == .3} equal\else different\fi \NC \NR
+\stoptabulate
+
+And what happens when we do more complex calculations:
+
+\starttabulate[|Tr|l|]
+\NC \type {math .sin(0.1 + 0.2) == math .sin(0.3)} \NC \luaexpr{tostring(math.sin(0.1 + 0.2) == math.sin(0.3))} \NC \NR
+\NC \type {posit.sin(0.1 + 0.2) == posit.sin(0.3)} \NC \positunum{sin(0.1 + 0.2) == sin(0.3)} \NC \NR
+\stoptabulate
+
+Of course other numbers might work out differently! I just took the simple tests
+that came to mind.
+
+So what are these posits? Here it's enough to know that they are a different way
+to store numbers with fractions. They still can loose precision but a bit less on
+smaller values and often we have relative small values in \TEX. Here are some links:
+
+\starttyping
+https://www.johngustafson.net/pdfs/BeatingFloatingPoint.pdf
+https://posithub.org/conga/2019/docs/14/1130-FlorentDeDinechin.pdf
+\stoptyping
+
+There are better explanations out there than I can provide (if at all). When I
+first read about these unums (a review of the 2015 book \quotation {The End of
+Error Unum Computing}) I was intrigued and when in 2023 I read something about it
+in relation to RISCV I decided to just add this playground for the users. After
+all we also have decimal support. And interval based solutions might actually be
+good for \METAPOST, so that is why we have it as extra number model. There we
+need to keep in mind that \METAPOST\ in non scaled models also apply some of the
+range checking and clipping that happens in scaled (these magick 4096 tricks).
+
+For now it is enough to know that it's an alternative for floats that {\em could}
+work better in some cases but not all. The presentation mentioned above gives
+some examples of physics constants where 32 posits are not good enough for
+encoding the extremely large or small constants, but for $\pi$ it's all fine.
+\footnote {Are 64 bit posits actually being worked on in softposit? There are
+some commented sections. We also need to patch some unions to make it compile as
+C.} In double mode we actually have quite good precision compared to 32 bit
+posits but with 32 bit floats we gain some. Very small numbers and very large
+numbers are less precise, but around 1 we gain: the next value after 1 is
+1.0000001 for a float and 1.000000008 for a posit (both 32 bit). So, currently
+for \METAPOST\ there is no real gain but if we'd add posits to \TEX\ we could
+gain some because there a halfword (used for storing data) is 32 bit.
+
+But how about \TEX ? Per April 2023 the \LUAMETATEX\ engine has native support
+for floats (this in addition to \LUA\ based floats that we already had in
+\CONTEXT). How that works can be demonstrated with some examples. The float
+related commands are similar to those for numbers and dimensions: \typ
+{\floatdef}, \typ {\float}, \typ {\floatexpr}, \typ {\iffloat}, \typ
+{\ifzerofloat} and \typ {\ifintervalfloat}. That means that we also have them as
+registers. The \typ {\positdef} primitive is similar to \typ {\dimensiondef}.
+When a float (posit) is seen in a dimension context it will be interpreted as
+points, and in an integer context it will be a rounded number. As with other
+registers we have a \typ {\newfloat} macro. The \typ {\advance}, \typ
+{\multiply} and \typ {\divide} primitives accept floats.
+
+\startbuffer[reset]
+\scratchdimen=1.23456pt
+\scratchfloat=1.23456
+\stopbuffer
+
+\typebuffer[reset] \getbuffer[reset]
+
+We now use these two variables in an example:
+
+\startbuffer[dimensions]
+\setbox0\hbox to \scratchdimen {x}\the\wd0
+\scratchdimen \dimexpr \scratchdimen * 2\relax
+\setbox0\hbox to \scratchdimen {x}\the\wd0
+\advance \scratchdimen \scratchdimen
+\setbox0\hbox to \scratchdimen {x}\the\wd0
+\multiply\scratchdimen by 2
+\setbox0\hbox to \scratchdimen {x}\the\wd0
+\stopbuffer
+
+\typebuffer[dimensions] \startlines\darkblue\tttf\getbuffer[reset,dimensions]\stoplines
+
+When we use floats we get this:
+
+\startbuffer[floats]
+\setbox0\hbox to \scratchfloat {x}\the\wd0
+\scratchfloat \floatexpr \scratchfloat * 2\relax
+\setbox0\hbox to \scratchfloat {x}\the\wd0
+\advance \scratchfloat \scratchfloat
+\setbox0\hbox to \scratchfloat {x}\the\wd0
+\multiply\scratchfloat by 2
+\setbox0\hbox to \scratchfloat {x}\the\wd0
+\stopbuffer
+
+\typebuffer[floats] \startlines\darkblue\tttf\getbuffer[reset,floats]\stoplines
+
+So which approach is more accurate? At first sight you might think that the
+dimensions are better because in the last two lines they indeed duplicate.
+However, the next example shows that with dimensions we lost some between steps.
+
+\startbuffer[noboxes]
+ \the\scratchfloat
+\scratchfloat \floatexpr \scratchfloat * 2\relax \the\scratchfloat
+\advance \scratchfloat \scratchfloat \the\scratchfloat
+\multiply\scratchfloat by 2 \the\scratchfloat
+\stopbuffer
+
+\typebuffer[noboxes] \startlines\darkblue\tttf\getbuffer[reset,noboxes]\stoplines
+
+One problem with accuracy is that it can build up. So when one eventually does
+some comparison the expectations can be wrong.
+
+\startbuffer
+\dimen0=1.2345pt
+\dimen2=1.2345pt
+
+\ifdim \dimen0=\dimen2 S\else D\fi \space +0sp: [dim]
+\ifintervaldim0sp\dimen0 \dimen2 O\else D\fi \space +0sp: [0sp]
+
+\advance\dimen2 1sp
+
+\ifdim \dimen0=\dimen2 S\else D\fi \space +1sp: [dim]
+\ifintervaldim 1sp \dimen0 \dimen2 O\else D\fi \space +1sp: [1sp]
+\ifintervaldim 1sp \dimen2 \dimen0 O\else D\fi \space +1sp: [1sp]
+\ifintervaldim 2sp \dimen0 \dimen2 O\else D\fi \space +1sp: [2sp]
+\ifintervaldim 2sp \dimen2 \dimen0 O\else D\fi \space +1sp: [2sp]
+
+\advance\dimen2 1sp
+
+\ifintervaldim 1sp \dimen0\dimen2 O\else D\fi \space +2sp: [1sp]
+\ifintervaldim 1sp \dimen2\dimen0 O\else D\fi \space +2sp: [1sp]
+\ifintervaldim 5sp \dimen0\dimen2 O\else D\fi \space +2sp: [5sp]
+\ifintervaldim 5sp \dimen2\dimen0 O\else D\fi \space +2sp: [5sp]
+\stopbuffer
+
+\typebuffer
+
+Here we show a test for overlap in values, the same can be done with integer
+numbers (counts) and floats. This interval checking is an experiment and we'll
+see it if gets used.
+
+\startpacked\darkblue \tttf \getbuffer \stoppacked
+
+There are also \typ {\ifintervalfloat} and \typ{\ifintervalnum}. Because I have
+worked around these few scaled point rounding issues for decades, it might
+actually take some time before we see the interval tests being used in \CONTEXT.
+After all, there is no reason to touch somewhat tricky mechanism without reason
+(read: users complaining).
+
+To come back to posits, just to be clear, we use 32 bit posits and not 32 bit
+floats, which we could have but that way we gain some accuracy because less bits
+are used by default for the exponential.
+
+In \CONTEXT\ we also provide a bunch of pseudo primitives. These take one float:
+\type {\pfsin}, \type {\pfcos}, \type {\pftan}, \type {\pfasin}, \type {\pfacos},
+\type {\pfatan}, \type {\pfsinh}, \type {\pfcosh}, \type {\pftanh}, \type
+{\pfasinh}, \type {\pfacosh}, \type {\pfatanh}, \type {\pfsqrt}, \type {\pflog},
+\type {\pfexp}, \type {\pfceil}, \type {\pffloor}, \type {\pfround}, \type
+{\pfabs}, \type {\pfrad} and \type {\pfdeg}, whiel these expect two floats: \type
+{\pfatantwo}, \type {\pfpow}, \type {\pfmod} and \type {\pfrem}.
+
+% \pageextragoal = 5sp
+
+\stopsectionlevel
+
+\startsectionlevel[title=\METAPOST]
+
+In addition to the instances \typ {metafun} (double in \LMTX), \typ {scaledfun},
+\typ {doublefun}, \typ {decimalfun} we now also have \typ {positfun}. Because we
+currently use 32 bit posits in the new number system there is no real gain over
+the already present 64 bit doubles. When 64 bit posits show up we might move on
+to that.
+
+\stopsectionlevel
+
+\startsectionlevel[title=\LUA]
+
+We support posits in \LUA\ too. Here we need to create a posit user data
+object. The usual metatable magick kicks in:
+
+\starttyping
+local p = posit.new(123.456)
+local q = posit.new(789.123)
+local r = p + q
+\stoptyping
+
+Here we just mention what is currently interface. The management functions are:
+\typ {new}, \type {copy}, \typ {tostring}, \typ {tonumber}, \typ {integer}, \typ
+{rounded}, \typ {toposit} and \typ {fromposit}. The usual operators are also
+supported: \type{+}, \type{-}, \type{*}, \type{/}, \type{^}, as well as the
+binary \type {|}. \type {&}, \type {~}, \type {<<} and \type {>>}. We can compare
+with \type {==}, \type {>=}, \type {<=} and \type {~=}. The more verbose \type
+{bor}, \type {bxor}, \type {band}, \type {shift}, \type {rotate} are there too.
+
+There is a subset of math provided: \type {min}, \type {max}, \type {abs}, \type
+{conj}, \type {modf}, \type {acos}, \type {asin}, \type {atan}, \type {ceil},
+\type {cos}, \type {exp}, \type {exp2}, \type {floor}, \type {log}, \type
+{log10}, \type {log1p}, \type {log2}, \type {logb}, \type {pow}, \type {round},
+\type {sin}, \type {sqrt} and \type {tan}. Somewhat special are \type {NaN} and
+\type {NaR}.
+
+Currently integer division (\type {//}) and modulo (\type {%}) are not available,
+but that might happen at some time.
+
+\stopsectionlevel
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-alignments.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-alignments.tex
index a70e222ea77..7962e5420ed 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-alignments.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-alignments.tex
@@ -624,10 +624,11 @@ Spans are applied at the end so you see a mix of templates applied.
{\showboxes\getbuffer[blownup-2]}
-When you define an alignment inside a macro, you need to duplicate the \type {\alignmark}
-signals. This is similar to embedded macro definitions. But in \LUAMETATEX\ we can get
-around that by using \type {\aligncontent}. Keep in mind that when the preamble is scanned there
-is no doesn't expand with the exception of the token after \type {\span}.
+When you define an alignment inside a macro, you need to duplicate the \type
+{\alignmark} signals. This is similar to embedded macro definitions. But in
+\LUAMETATEX\ we can get around that by using \type {\aligncontent}. Keep in mind
+that when the preamble is scanned there is no doesn't expand with the exception
+of the token after \type {\span}.
\startbuffer
\halign \bgroup
@@ -792,6 +793,163 @@ like tabulate.
\stopsectionlevel
+\startsectionlevel[title=Templates]
+
+The \type {\omit} command signals that the template should not be applied. But
+what if we actually want something at the left and right of the content? Here is
+how it's done:
+
+\startbuffer
+\tabskip10pt \showboxes
+\halign\bgroup
+ [\hss\aligncontent\hss]\aligntab
+ [\hss\aligncontent\hss]\aligntab
+ [\hss\aligncontent\hss]\cr
+ x\aligntab x\aligntab x\cr
+ xx\aligntab xx\aligntab xx\cr
+ xxx\aligntab xxx\aligntab xxx\cr
+ \omit oo\aligntab\omit oo\aligntab\omit oo\cr
+ xx\aligntab\realign{\hss(}{)\hss}xx\aligntab xx\cr
+ \realign{\hss(}{)\hss}xx\aligntab xx\aligntab xx\cr
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The \type {\realign} command is like an \type {omit} but it expects two token
+lists that will for this cell be used instead of the ones from the preamble.
+While \type {\omit} also skips insertion of \type {\everytab}, here it is
+inserted, just like with normal preambles.
+
+\start \blank \getbuffer \blank \stop
+
+It will probably take a while before I'll apply this in \CONTEXT\ because changing
+existing (stable) table environment is not something done lightly.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Pitfalls]
+
+Alignment have a few properties that can catch you off|-|guard. One is the use of
+\type {\everycr}. The next example demonstrates that it is also injected after the
+preamble definition.
+
+\startbuffer
+\everycr{\noalign{\hrule}}
+\halign\bgroup \hsize 5cm \strut \alignmark\cr one\cr two\cr\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This makes sense because it is one way to make sure that for instance a rule gets
+the width of the cell.
+
+\startpacked
+\showboxes \getbuffer
+\stoppacked
+
+The sam eis of course true for a vertical align:
+
+\startbuffer
+\everycr{\noalign{\vrule}}
+\valign\bgroup \hsize 4cm \strut \aligncontent\cr one\cr two\cr\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We set the width because otherwise the current text width is used.
+
+\startpacked
+\showboxes \getbuffer
+\stoppacked
+
+Something similar happens with a \type {\tabskip}: the value set before the
+alignment is used left of the first cell.
+
+\startbuffer
+\tabskip10pt
+\halign\bgroup \tabskip20pt\relax\aligncontent\cr x\cr x\cr \egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startpacked
+\showboxes \getbuffer
+\stoppacked
+
+The \type {\tabskip} outside the alignment is an internal glue register so you
+can for instance use the prefix \type {\global}. However, in a preamble it is
+more a directive: the given value is stored with the cell. This means that the
+next code is invalid:
+
+\starttyping
+\tabskip10pt
+\halign\bgroup \global\tabskip20pt\relax\aligncontent\cr x\cr x\cr \egroup
+\stoptyping
+
+The parser looks at tokens in the preamble, sees the \type {\global} and appends
+it to the current pre|-|part of the cell's template. Then it sees a \type
+{\tabskip} and assigns the value after it to the cell's skip. The token and its
+value just disappear, they are not appended to the template. Now, when the
+template is injected (and interpreted) this \type {\global} expects a variable
+next and in our case the \type {x} doesn't qualify. The next snippet however works
+okay:
+
+\startbuffer
+\scratchcounter0
+\halign\bgroup
+ \global\tabskip40pt\relax\advance\scratchcounter\plusone\aligncontent\cr
+ x:\the\scratchcounter\cr
+ x:\the\scratchcounter\cr
+ x:\the\scratchcounter\cr
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Here the \type {\global} is applied to the \type {advance} because the skip
+definition is {\em not} in the preamble.
+
+\start \blank \getbuffer \blank \stop
+
+Here is a variant:
+
+\startbuffer
+\scratchcounter0
+\halign\bgroup
+ \global\tabskip10pt\relax\aligncontent\cr
+ \advance\scratchcounter\plusone x:\the\scratchcounter\cr
+ \advance\scratchcounter\plusone x:\the\scratchcounter\cr
+ \advance\scratchcounter\plusone x:\the\scratchcounter\cr
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Again the \type {\global} stays and this time if ends up before the content which
+starts with an \type {\advance}.
+
+\start \getbuffer \stop
+
+Normally you will not need the next trickery but it shows that cells are grouped:
+
+\startbuffer
+\halign\bgroup\aligncontent\cr
+ 1\atendofgrouped{A}\atendofgrouped{B}\cr
+ 2\aftergrouped {A}\aftergrouped {B}\cr
+ 3 \cr
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Maybe at some point I'll add something a bit more tuned for dealing with cells,
+but here is what you get with the above:
+
+\getbuffer
+
+\stopsectionlevel
+
\startsectionlevel[title=Remark]
It can be that the way alignments are interfaced with respect to attributes is a bit
@@ -828,3 +986,14 @@ to add these.
% \omit\span \hss ccc\hss\cr
% \egroup \egroup
% \egroup
+
+% \protected\def\oof#1{[#1]}
+% \def\foo{\aligncontent}
+% \def\foo{\oof{\aligncontent}}
+
+% \halign\bgroup
+% \hss\span\foo\hss\cr
+% x\cr
+% \omit xx\cr
+% xxx\cr
+% \egroup
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 e2e34bd20a8..086b1313177 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
@@ -177,7 +177,6 @@ some so called struts to enforce a consistent height and depth. A strut is an
invisible quantity (consider it a black box) that enforces consistent line
dimensions: height and depth.
-
\startlinecorrection
{\dontcomplain\hbox{\showstruts\showboxes\getbuffer}}
\stoplinecorrection
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
index 12d12f7f4d4..47d79648615 100644
--- 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
@@ -12,7 +12,7 @@ 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.
-\stopsectionlevel
+% \stopsectionlevel
\startsectionlevel[title=\PASCAL]
@@ -36,7 +36,7 @@ to pack a sequence of statements.
In \TEX\ macros (or source code) the following can occur:
-\starttyping
+\starttyping[option=TEX]
\begingroup
...
\endgroup
@@ -44,7 +44,7 @@ In \TEX\ macros (or source code) the following can occur:
as well as:
-\starttyping
+\starttyping[option=TEX]
\bgroup
...
\egroup
@@ -54,7 +54,7 @@ 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
+\starttyping[option=TEX]
\scratchcounter=1
\def\foo{foo}
\begingroup
@@ -70,7 +70,7 @@ 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
+\starttyping[option=TEX]
\bgroup
\endgroup
\stoptyping
@@ -86,19 +86,19 @@ of \TEX.
The \METAPOST\ language also has a concept of grouping but in this case it's more like a
programming language.
-\starttyping
+\starttyping[option=MP]
begingroup ;
n := 123 ;
-engroup ;
+endgroup ;
\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
+\starttyping[option=MP]
begingroup ;
save n ; numeric n ; n := 123 ;
-engroup ;
+endgroup ;
\stoptyping
Given the use of \METAPOST\ (read: \METAFONT) this makes a lot of sense: often
@@ -116,7 +116,7 @@ saved inside a group.
In \LUA\ all assignments are global unless a variable is defines local:
-\starttyping
+\starttyping[option=LUA]
local x = 1
local y = 1
for i = 1, 10 do
@@ -153,4 +153,305 @@ statement end, while in \METAPOST\ it does end a statement (expression).
\stopsectionlevel
+\stopsectionlevel
+
+\startsectionlevel[title=Kinds of grouping]
+
+Explicit grouping is accomplished by the two grouping primitives:
+
+\starttyping[option=TEX]
+\begingroup
+ \sl render slanted here
+\endgroup
+\stoptyping
+
+However, often you will find this being used:
+
+\starttyping[option=TEX]
+{\sl render slanted here}
+\stoptyping
+
+This is not only more compact but also avoids the \type {\endgroup} gobbling
+following spaces when used inline. The next code is equivalent but also suffers
+from the gobbling:
+
+\starttyping[option=TEX]
+\bgroup
+ \sl render slanted here
+\egroup
+\stoptyping
+
+The \type {\bgroup} and \type {\egroup} commands are not primitives but aliases
+(made by \type {\let}) to the left and right curly brace. These two characters
+have so called category codes that signal that they can be used for grouping. The
+{\em can be} here suggest that there are other purposes and indeed there are, for
+instance in:
+
+\starttyping[option=TEX]
+\toks 0 = {abs}
+\hbox {def}
+\stoptyping
+
+In the case of a token list assignment the curly braces fence the assignment, so scanning
+stops when a matching right brace is found. The following are all valid:
+
+\starttyping[option=TEX]
+\toks 0 = {a{b}s}
+\toks 0 = \bgroup a{b}s}
+\toks 0 = {a{\bgroup b}s}
+\toks 0 = {a{\egroup b}s}
+\toks 0 = \bgroup a{\bgroup b}s}
+\toks 0 = \bgroup a{\egroup b}s}
+\stoptyping
+
+They have in common that the final fence has to be a right brace. That the first
+one can be a an alias is due to the fact that the scanner searches for a brace
+equivalent when it looks for the value. Because the equal is optional, there is
+some lookahead involved which involves expansion and possibly push back while
+once scanning for the content starts just tokens are collected, with a fast
+check for nested and final braces.
+
+In the case of the box, all these specifications are valid:
+
+\starttyping[option=TEX]
+\hbox {def}
+\hbox \bgroup def\egroup
+\hbox \bgroup def}
+\hbox \bgroup d{e\egroup f}
+\hbox {def\egroup
+\stoptyping
+
+This is because now the braces and equivalent act as grouping symbols so as long
+as they match we're fine. There is a pitfall here: you cannot mix and match
+different grouping, so the next issues an error:
+
+\starttyping[option=TEX]
+\bgroup xxx\endgroup % error
+\begingroup xxx\egroup % error
+\stoptyping
+
+This can make it somewhat hard to write generic grouping macros without trickery
+that is not always obvious to the user. Fortunately it can be hidden in macros
+like the helper \typ {\groupedcommand}. In \LUAMETATEX\ we have a clean way out
+of this dilemma:
+
+\starttyping[option=TEX]
+\beginsimplegroup xxx\endsimplegroup
+\beginsimplegroup xxx\endgroup
+\beginsimplegroup xxx\egroup
+\stoptyping
+
+When you start a group with \typ {\beginsimplegroup} you can end it in the three
+ways shows above. This means that the user (or calling macro) doesn't take into
+account what kind of grouping was used to start with.
+
+When we are in math mode things are different. First of all, grouping with \typ
+{\begingroup} and \typ {\endgroup} in some cases works as expected, but because
+the math input is converted in a list that gets processed later some settings can
+become persistent, like changes in style or family. You can bet better use \typ
+{\beginmathgroup} and \typ {\endmathgroup} as they restore some properties. We
+also just mention the \type {\frozen} prefix that can be used to freeze
+assignments to some math specific parameters inside a group.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Hooks]
+
+In addition to the original \type {\aftergroup} primitive we have some more
+hooks. They can best be demonstrated with an example:
+
+\startbuffer
+\begingroup \bf
+ %
+ \aftergroup A \aftergroup 1
+ \atendofgroup B \atendofgroup 1
+ %
+ \aftergrouped {A2}
+ \atendofgrouped {B2}
+ %
+ test
+\endgroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+These collectors are accumulative. Watch how the bold is applied to what we
+inject before the group ends.
+
+\getbuffer
+
+\stopsectionlevel
+
+\startsectionlevel[title=Local versus global]
+
+When \TEX\ enters a group and an assignment is made the current value is stored
+on the save stack, and at the end of the group the original value is restored. In
+\LUAMETATEX\ this mechanism is made a bit more efficient by avoiding redundant
+stack entries. This is also why the next feature can give unexpected results when
+not used wisely.
+
+Now consider the following example:
+
+\startbuffer
+\newdimension\MyDimension
+
+\starttabulate[||||]
+ \NC \MyDimension10pt \the\MyDimension
+ \NC \advance\MyDimension10pt \the\MyDimension
+ \NC \advance\MyDimension10pt \the\MyDimension \NC \NR
+ \NC \MyDimension10pt \the\MyDimension
+ \NC \advance\MyDimension10pt \the\MyDimension
+ \NC \advance\MyDimension10pt \the\MyDimension \NC \NR
+\stoptabulate
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+The reason why we get the same values is that cells are a group and therefore the
+value gets restored as we move on. We can use the \type {\global} prefix to get
+around this
+
+\startbuffer
+\starttabulate[||||]
+ \NC \global \MyDimension10pt \the\MyDimension
+ \NC \global\advance\MyDimension10pt \the\MyDimension
+ \NC \global\advance\MyDimension10pt \the\MyDimension \NC \NR
+ \NC \global \MyDimension10pt \the\MyDimension
+ \NC \global\advance\MyDimension10pt \the\MyDimension
+ \NC \global\advance\MyDimension10pt \the\MyDimension \NC \NR
+\stoptabulate
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+Instead of using a global assignment and increment we can also use the following
+
+\startbuffer
+\constrained\MyDimension\zeropoint
+\starttabulate[||||]
+ \NC \retained \MyDimension10pt \the\MyDimension
+ \NC \retained\advance\MyDimension10pt \the\MyDimension
+ \NC \retained\advance\MyDimension10pt \the\MyDimension \NC \NR
+ \NC \retained \MyDimension10pt \the\MyDimension
+ \NC \retained\advance\MyDimension10pt \the\MyDimension
+ \NC \retained\advance\MyDimension10pt \the\MyDimension \NC \NR
+\stoptabulate
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+So what is the difference with the global approach? Say we have these two buffers:
+
+\startbuffer
+\startbuffer[one]
+ \global\MyDimension\zeropoint
+ \framed {
+ \framed {\global\advance\MyDimension10pt \the\MyDimension}
+ \framed {\global\advance\MyDimension10pt \the\MyDimension}
+ }
+ \framed {
+ \framed {\global\advance\MyDimension10pt \the\MyDimension}
+ \framed {\global\advance\MyDimension10pt \the\MyDimension}
+ }
+\stopbuffer
+
+\startbuffer[two]
+ \global\MyDimension\zeropoint
+ \framed {
+ \framed {\global\advance\MyDimension10pt \the\MyDimension}
+ \framed {\global\advance\MyDimension10pt \the\MyDimension}
+ \getbuffer[one]
+ }
+ \framed {
+ \framed {\global\advance\MyDimension10pt \the\MyDimension}
+ \framed {\global\advance\MyDimension10pt \the\MyDimension}
+ \getbuffer[one]
+ }
+\stopbuffer
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+Typesetting the second buffer gives us:
+
+\startlinecorrection
+\getbuffer[two]
+\stoplinecorrection
+
+When we want to have these entities independent and not use different variables,
+the global settings bleeding from one into the other entity is messy. Therefore
+we can use this:
+
+\startbuffer
+\startbuffer[one]
+ \constrained\MyDimension\zeropoint
+ \framed {
+ \framed {\retained \MyDimension10pt \the\MyDimension}
+ \framed {\retained\advance\MyDimension10pt \the\MyDimension}
+ }
+ \framed {
+ \framed {\retained \MyDimension10pt \the\MyDimension}
+ \framed {\retained\advance\MyDimension10pt \the\MyDimension}
+ }
+\stopbuffer
+
+\startbuffer[two]
+ \constrained\MyDimension\zeropoint
+ \framed {
+ \framed {\retained\advance\MyDimension10pt \the\MyDimension}
+ \framed {\retained\advance\MyDimension10pt \the\MyDimension}
+ \getbuffer[one]
+ }
+ \framed {
+ \framed {\retained\advance\MyDimension10pt \the\MyDimension}
+ \framed {\retained\advance\MyDimension10pt \the\MyDimension}
+ \getbuffer[one]
+ }
+\stopbuffer
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+Now we get this:
+
+\startlinecorrection
+\getbuffer[two]
+\stoplinecorrection
+
+The \type {\constrained} prefix makes sure that we have a stack entry, without
+being clever with respect to the current value. Then the \type {\retained} prefix
+can do its work reliably and avoid pushing the old value on the stack. Without
+the constrain it gets a bit unpredictable because then it all depends on where
+further up the chain the value was put on the stack. Of course one can argue that
+we should not have the \quotation {save stack redundant entries optimization} but
+that's not going to be removed.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Files]
+
+Although it doesn't really fit in this chapter, here are some hooks into processing
+files:
+
+\starttyping[option=TEX]
+Hello World!\atendoffiled {\writestatus{FILE}{ATEOF B #1}}\par
+Hello World!\atendoffiled {\writestatus{FILE}{ATEOF A #1}}\par
+Hello World!\atendoffiled reverse {\writestatus{FILE}{ATEOF C #1}}\par
+Hello World!\begingroup\sl \atendoffiled {\endgroup}\par
+\stoptyping
+
+Inside a file you can register tokens that will be expanded when the file ends.
+You can also do that beforehand using a variant of the \type {\input} primitive:
+
+\starttyping[option=TEX]
+\eofinput {\writestatus{FILE}{DONE}} {thatfile.tex}
+\stoptyping
+
+This feature is mostly there for consistency with the hooks into groups and
+paragraphs but also because \type {\everyeof} is kind of useless given that one
+never knows beforehand if a file loads another file. The hooks mentioned above
+are bound to the current file.
+
+\stopsectionlevel
+
\stopdocument
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-lines.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-lines.tex
new file mode 100644
index 00000000000..e2df3fa0309
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-lines.tex
@@ -0,0 +1,1178 @@
+% language=us runpath=texruns:manuals/lowlevel
+
+\environment lowlevel-style
+
+\startdocument
+ [title=lines,
+ coauthor=Mikael Sundqvist,
+ color=middleorange]
+
+\startsectionlevel[title=Introduction]
+
+There is no doubt that \TEX\ does an amazing job of \quotation {breaking
+paragraphs into lines} where a paragraph is a sequence of words in the input
+separated by spaces or its equivalents (single line endings turned space). The
+best descriptions of how that is done can be found in Don Knuths \quotation {The
+\TEX\ Book}, \quotation {\TEX\ The Program} and \quotation {Digital Typography}.
+Reading and rereading the relevant portions of those texts is a good exercise in
+humility.
+
+That said, whatever follows here builds upon what Knuth gave us and in no way we
+pretend to do better than that. It started out as a side track of improving
+rendering math in combination with more control over breaking inline math. It
+pretty much about having fun with the par builder but in the end can also help
+make your results look better. This is especially true for proze.
+
+Trying to describe the inner working of the par builder makes no sense. Not only
+is it kind of complex, riddled with magic constants and heuristics, but there is
+a good chance for us to talk nonsense thanks to misunderstanding. However, some
+curious aspects will be brought up. Consider what follows a somewhat naive
+approach and whatever goes wrong, blame the authors, not \TEX.
+
+If you're one of those reader who love to complain about the bad manuals, you can
+stop reading here. There is plenty said in the mentioned books but you can also
+consult Viktor Eijkhouts excellent \quotation {\TEX\ by Topic} (just search the
+web for how the get these books). If you're curious and in for some adventure,
+keep reading.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Warning]
+
+This is a first version. What is described here will stay but is still
+experimental and how it evolves also depends on what demands we get from the
+users. We have defined some experimental setups in \CONTEXT. We wil try to
+improve the explanations in ways that (we hope) makes clear what happens deep
+down but that takes time. These might change depending on feedback. We assume
+that we're in granular mode:
+
+\starttyping
+\setupalign[granular]
+\stoptyping
+
+We will explain below what that means, but let us already now make clear that
+this will likely become the default! As far as we can see, due to the larger
+solution space, the inter-word spacing is more even but that also means that some
+paragraphs can become one line less or more.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Constructing paragraphs]
+
+There are several concepts at work when \TEX\ breaks a paragraph into lines. Here
+we assume that we talk about text: words separated by spaces. We also assume that
+the text starts at the left edge and nicely runs till the right edge, with the
+exception of the last line.
+
+\startitemize
+\startitem
+ The spaces between words can stretch or shrink. We don't want that to be too
+ inconsistent (visible) between two lines. This is where the terms loose and
+ tight come into play.
+\stopitem
+\startitem
+ Words can be hyphenated but we don't want that to happen too often. We also
+ discourage neighboring lines to have hyphens. Hyphenating the (pre) final line
+ is also sort of bad.
+\stopitem
+\startitem
+ We definitely don't want words to stick out in the margin. If we have to choose,
+ stretching is preferred over shrinking. If spaces become too small words,
+ start to blur.
+\stopitem
+\startitem
+ If needed glyphs can stretch or shrink a little in order to get rid of
+ excessive spacing. But we really want to keep it minimal, and avoid it when
+ possible. Usually we permit more stretch than shrink. Not all scripts (and
+ fonts for that matter) might work well with this feature.
+\stopitem
+\startitem
+ As a last resort we can stretch spaces so that we get rid of any still
+ sticking out word. When \TEX\ reports an overfull box (often a line) you have
+ to pay attention!
+\stopitem
+\stopitemize
+
+When \TEX\ decides where to break and when to finish doing so it uses a system of
+penalties and demerits and at some point makes decisions with regards to how bad
+a breakpoint (and eventually a paragraph) is. The penalties are normally
+relatively small unless we really want to penalize. When \TEX\ is in the process
+of breaking a paragraph it calculates badness values for each line. This can be
+seen as a measure on how bad looking a line is; a badness of zero is good, but
+the larger the badness becomes, the worse the line is.
+
+Here we shortly summarize the parameters that play a role in calculating what
+\TEX\ calls the costs of breaking a line at some point: it's a combination of
+weighting penalties as well as over- or undershooting the line with, where the
+amount (dimension) and kind of (fillers) stretch and shrink determien the final
+verdict.
+
+\startbuffer
+\ruledhbox to 20 ts{left \hss right}
+\ruledhbox to 40 ts{left \hss right}
+\ruledhbox to 5 ts{left \hss right}
+\ruledhbox to 5 ts{left right}
+\ruledhbox to 5 es{%
+ left
+ \hskip 1ts plus 0.5ts\relax
+ middle
+ \hskip 1ts plus 1.5ts\relax
+ right%
+}
+\stopbuffer
+
+\typebuffer
+
+These boxes show a bit what happens with spacing that can stretch of shrink. The
+first three cases are not bad because it's what we ask for with the wildcard
+\type {\hss}. \footnote {We use this opportunity to promote the new \type {ts} and
+\type {es} units.}
+
+\startlines \getbuffer \stoplines
+
+\TEX\ will run over each paragraph at most three times. On each such run, it will
+choose different breakpoints, calculate badness of each possible line, combine
+that with eventual penalties, and calculate a certain demerit value for each
+possible paragraph. It creats a set of solutions as it progresses, discards the
+worse cases so far and eventually ends of what it thinks is best.
+
+The process is primarily controlled by these parameters:
+
+\startitemize
+\startitem
+ \type {\pretolerance}: This number determines the success of the first, not
+ hyphenated pass. Often the value is set to the plain \TEX\ value of 100.
+ If \TEX\ finds a possible division of a paragraph such that no line has
+ a badness higher than \type {\pretolerance}, the algorithm quits here and
+ that line is chosen.
+\stopitem
+\startitem
+ \type {\tolerance}: This number determines the success of the second,
+ hyphenated pass. Often the value is set to the plain \TEX\ value of 200.
+\stopitem
+\startitem
+ \type {\emergencystretch}: This dimension kicks in when the second pass is
+ not successful. In \CONTEXT\ we often set it to \type {2\bodyfontsize}.
+\stopitem
+\stopitemize
+
+When we are (in \CONTEXT\ speak) \type {tolerant}, we have a value of 3000, while
+\type {verytolerant} bumps it to 4500. These are pretty large values compared to
+the default 100 and 200 that seem to cover most cases well, especially when we
+have short words, a reasonable width and lots of opportunities for hyphenation.
+Keep in mind that a macro package has to default to values that make sense for
+the average case.
+
+We now come to the other relevant parameters. You need to keep in mind that the
+demerits are made from penalty values that get squared which is why parameters
+with demerits in their name have high values: a penalty of $50$ squared has to
+relate to a demerit of $5000$, so we might have $2500 + 5000$ at some point.
+
+The formula (most often) used to calculate the demerits \im{d} is
+
+\startformula
+ d = (l + b + p)^2 + e
+\stopformula
+
+Here \im {l} is the \type {\linepenalty}, set to \im {10} in plain, \im {b} is the
+badness of the line, and \im {p} is the penalty of the current break (for example,
+added by hyphenation, or by breaking an inline formula). The \im {e} stands for
+extra non-local demerits, that do not depend on only the current line, like
+the \type {\doublehyphendemerits} that is added if two lines in a row are
+hyphenated.
+
+The badness reflects how the natural linewidth relates to the target width and
+uses a cubic function. A badness of zero is of course optimal, but a badness of
+99 is pretty bad. A magic threshold is 12 (around that value a line is considered
+decent). If you look at the formula above you can now understand why the line
+penalty defaults to the low value of 10.
+
+\startitemize
+\startitem
+ \type {\hyphenpenalty}: When a breakpoint occurs at a discretionary this one
+ gets added. In \LUAMETATEX\ we store penalties in the discretionary nodes but
+ user defined \typ {\discretionary}'s can carry dedicated penalties. This
+ value is set to 50, which is not that much. Large values reduce the solution
+ space so best keep this one reasonable.
+\stopitem
+\startitem
+ \type {\linepenalty}: Normally this is set to 10 and it is the baseline for a
+ breakpoint. This is again a small value compared to for instance the
+ penalties that you find in inline math. There we need some breakpoints and
+ after binary and relation symbols such an opportunity is created. The
+ specific penalties are normally 500 and 700. One has to keep in mind, as
+ shown in the formula above, that the penalties are not acting on a linear
+ scale when the demerits are calculated. Math spacing and penalty control is
+ discussed in the (upcoming) math manual.
+\stopitem
+\startitem
+ \type {\doublehyphendemerits}: Because it is considered bad to have two
+ hyphens in a row this is often set pretty high, many thousands. These are
+ treated as demerits (so outside of the squared part of the above formula).
+\stopitem
+\startitem
+ \type {\finalhyphendemerits}: The final (pre last) line having a hyphen is
+ also considered bad. The last line is handled differently anyway, just
+ because it gets normally flushed left.
+\stopitem
+\startitem
+ \type {\adjdemerits}: lines get rated in terms of being loose, decent, tight,
+ etc. When two lines have a different rating we bump the total demerits.
+\stopitem
+\startitem
+ \type {\looseness}: it is possible to force less or more lines but to what
+ extend this request is honored depends on for instance the possible
+ (emergency) stretch in the spaces (or any glue for that matter). `
+ % Needs an explanation
+\stopitem
+\stopitemize
+
+It is worth noticing that you can set \typ {\lastlinefit} such that the spaces in
+the last line will be comparable to those in the preceding line. This is a
+feature that \ETEX\ brought us. Anyways, keep in mind normally penalties are
+either small, or when we want to be tough, pretty high. Demerits are often
+relatively large.
+
+The next one is a flag that triggers expansion (or compression) of glyphs to kick
+in. Those get added to the available stretch and/or shrink of a line:
+
+\startitemize[continue]
+\startitem
+ \type {\adjustspacing}: Its value determines if expansion kicks in: glyphs
+ basically get a stretch and shrink value, something that helps filling our
+ lines. We only have zero, two and three (and not the \PDFTEX\ value of two):
+ three means \quote {only glyphs} and two means \quote {font kerns and
+ glyphs}.
+\stopitem
+\stopitemize
+
+In \LUAMETATEX\ we also have:
+
+\startitemize
+\startitem
+ \typ {\linebreakcriterion}: The normal distinction between loose, decent and
+ tight in \TEX\ uses 12 for 0.5 and 99 for about 1.0, but because we have more
+ granularity (.25) we can set four values instead. The default of zero (\type
+ {"0C0C0C63}) then becomes \type {"020C2A63}. When set that way the default
+ \typ {\adjdemerits} has to be halved 5000 so that we compare the more
+ granular distances. Don't worry if you \quote {don't get it}, hardly any user
+ will change these values. One can think of the 100 squared becomes a 10000
+ (at least this helps relating these numbers) and 10000 is pretty bad in \TEX s
+ perception.
+\stopitem
+\startitem
+ \type {\adjustspacingstep}: When set this one is are used instead of the font
+ bound value which permits local control without defining a new font instance.
+\stopitem
+\startitem
+ \type {\adjustspacingstretch}: idem.
+\stopitem
+\startitem
+ \type {\adjustspacingshrink}: idem.
+\stopitem
+% \startitem
+% \type {\extrahyphenpenalty}:
+% \stopitem
+\startitem
+ \type {\orphanpenalty}: This penalty will be injected before the last word of a paragraph.
+\stopitem
+\startitem
+ \type {\orphanpenalties}: Alternatively a series of penalties can be defined.
+ This primitive expects a count followed by that number of penalties. These
+ will be injected starting from the end.
+\stopitem
+\stopitemize
+
+The shape of a paragraph is determined by \typ {\hangindent}, \type {\hangafter},
+\typ {\parshape} and \typ {\parindent}. The width is controlled by \typ {\hsize},
+\typ {\leftskip}, \typ {\rightskip}. In addition there are \typ
+{\parinitleftskip}, \typ {\parinitrightskip}, \typ {\parfillleftskip} and \typ
+{\parfillrightskip} that control first and last lines.
+
+We also have these:
+
+\startitemize
+\startitem
+ \type {\linebreakpasses}: When set to one, the currently set \type {\parpasses}
+ will be applied.
+\stopitem
+\startitem
+ \type {\parpasses}: This primitive defined a set of sub passes that kick in
+ when the second pass is finished. This basically opens up the par builder. It
+ is still experimental and will be improved based upon user feedback. Although
+ it is a side effect of improving the breaking of extensive mixes of math and
+ text, it is also quite useful for text only (think novels).
+\stopitem
+\stopitemize
+
+In the next sections we will explain how these can improve the look and feel of
+what you typeset.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Subpasses]
+
+In \LUATEX\ and therefore also in \LUAMETATEX\ a paragraph is constructed in steps:
+
+\startitemize
+\startitem
+ The list of nodes that makes the paragraph is hyphenated: words become a
+ mixture of glyphs and discretionaries.
+\stopitem
+\startitem
+ That list is processed by a font handler that can remove, add or change glyphs
+ depending on how glyphs interact. This depends on the language and scripts used.
+\stopitem
+\startitem
+ The result is fed into the parbuilder that applies upto three passes as mentioned
+ before.
+\stopitem
+\stopitemize
+
+In traditional \TEX\ these three actions are combined into one and the overhead
+is shared. In the split case the processing time gets distributed and in practice
+the last action is not the one that takes most time. This is why the mechanism
+that we discuss next has little impact on the run: calling the par builder a few
+times more seldom results in more runtime. This is why in we support so called
+sub passes between the second and third one.
+
+Here is an example of a setup. We set a low tolerance for the first pass and second
+pass. We can do that because we don't need to play safe nor need to compromise.
+
+\starttyping
+\pretolerance 75
+\tolerance 150
+\parpasses 3
+ threshold 0.025pt
+ classes \indecentparpassclasses
+ tolerance 150
+ next
+ threshold 0.025pt
+ classes \indecentparpassclasses
+ tolerance 200
+ emergencystretch .25\bodyfontsize
+ next
+ threshold 0.025pt
+ classes \indecentparpassclasses
+ tolerance 200
+ optional 1
+ emergencystretch .5\bodyfontsize
+\relax
+\linebreakpasses 1
+\stoptyping
+
+Because we want to retain performance we need to test efficiently if we really
+need the (here upto three) additional passes, so let's see how it is done. When a
+pass list is defined, and line break passes are enabled, the engine will check {\em after}
+the second pass if some more work is needed. For that it will do a quick analysis and
+calculate four values:
+
+\startitemize[packed]
+\startitem overflow : the maximum value found, this is something really bad. \stopitem
+\startitem underflow : the maximum value found, this is something we can live with. \stopitem
+\startitem verdict : what is the worst badness of lines in this paragraph. \stopitem
+\startitem classified : what classes are assigned to lines, think looseness, decent and tight. \stopitem
+\stopitemize
+
+There are two cases where the engine will continue with the applying passes:
+there is an overflow or there is a verdict (max badness) larger than zero. When we
+tested this on some large documents we noticed that this is nearly always true,
+but by checking we save a few unnecessary passes.
+
+Next we test if a pass is really needed, and if not we check the next pass. When
+a pass is done, we pick up where we left, but we test for the overflow or badness
+every sub pass. The next checks make us run a pass:
+
+\startitemize[packed]
+\startitem overfull exceeds threshold \stopitem
+\startitem verdict exceeds badness \stopitem
+\startitem classified overlaps classes \stopitem
+\stopitemize
+
+Here \typ {threshold}, \typ {badness} and \typ {classes} are options in a pass
+section. Which test makes sense depends a bit on how \TEX\ sees the result.
+Internally \TEX\ uses numbers for its classification (0..5) but we map that onto
+a bitset because we want an overview:
+
+\starttabulate[|r|l|c|c|c|c|]
+\NC \NC \BC indecent \BC almostdecent \BC loose \BC tight \NC \NR
+\NC 1 \BC veryloose \NC + \NC + \NC + \NC \NC \NR
+\NC 2 \BC loose \NC + \NC + \NC + \NC \NC \NR
+\NC 4 \BC semiloose \NC + \NC \NC + \NC \NC \NR
+\NC 8 \BC decent \NC \NC \NC \NC \NC \NR
+\NC 16 \BC semitight \NC + \NC \NC \NC + \NC \NR
+\NC 32 \BC tight \NC + \NC + \NC \NC + \NC \NR
+\stoptabulate
+
+The semiloose and semitight values are something \LUAMETATEX. In \CONTEXT\ we
+have these four variants predefined as \typ {\indecentparpassclasses} and such.
+
+The sections in a par pass setup are separated by \type {next}. For testing
+purposes you can add \type {skip} and \type {quit}. The \type {threshold} tests
+against the overfull value, the \type {badness} against the verdict and \type
+{classes} checks for overlap with encountered classes, the classification.
+
+You can specify an \typ {identifier} in the first segment that then will be used
+in tracing but it is also passed to callbacks that relate to this feature.
+Discussing these callback is outside the scope fo this wrapup.
+
+You need to keep in mind that parameters are not reset to their original values
+between two subpasses of a paragraph.
+We have \typ {tolerance} and \typ {emergencystretch} which are handy for simple
+setups. When we start with a small tolerance we often need to bump that one. The
+stretch is likely a last resort. The usual demerits can be set too: \typ
+{doublehyphendemerits}, \typ {finalhyphendemerits} and \typ {adjdemerits}. We
+have \typ {extrahyphenpenalty} that gets added to the penalty in a discretionary.
+You can also set \typ {linepenalty} to a different value than it normally gets.
+
+The \typ {looseness} can be set but keep in mind that this only makes sense in
+very special cases. It's hard to be loose when there is not much stretch or shrink
+available. The \typ {linebreakcriterion} parameter can best be left untouched and is
+mostly there for testing purposes.
+
+The \LUAMETATEX\ specific \typ {orphanpenalty} gets injected before the last word
+in a paragraph. High values can lead to overfull boxes but when used in text that
+hyphenate well or with languages that have short words it might work out well.
+
+The next four parameters are related to expansion: \typ {adjustspacing}, \typ
+{adjustspacingstep}, \typ {adjustspacingshrink} and \typ {adjustspacingstretch}.
+Here we have several scenarios.
+
+\startitemize
+\startitem
+ Fonts are set up for expansion (in \CONTEXT\ for instance with the quality
+ specifier). When \type {hz} is then enabled it will always kick in.
+\stopitem
+\startitem
+ When we don't enable it, the par pass can do it by setting \typ {adjustspacing} (to 3).
+\stopitem
+\startitem
+ When the other parameters are set these will overload the ones in the font,
+ but used with the factors in there, so different characters get scaled
+ differently. You can set the step to one to get more granular results.
+\stopitem
+\startitem
+ When expansion is {\em not} set on the font, setting the options in a pass will activate
+ expansion but with the factors set to 1000. This means all characters are treated equal,
+ which is less subtle.
+\stopitem
+\stopitemize
+
+When a font is not set up to use expansion, you can do something like this:
+
+\starttyping
+\parpasses 6
+ classes \indecentparpassclasses
+ threshold 0.025pt
+ tolerance 250
+ extrahyphenpenalty 50
+ orphanpenalty 5000
+ % font driven
+ next ifadjustspacing
+ threshold 0.025pt
+ classes \tightparpassclasses
+ tolerance 300
+ adjustspacing 3
+ orphanpenalty 5000
+ next ifadjustspacing
+ threshold 0.025pt
+ tolerance 350
+ adjustspacing 3
+ adjustspacingstep 1
+ adjustspacingshrink 20
+ adjustspacingstretch 40
+ orphanpenalty 5000
+ emergencystretch .25\bodyfontsize
+ % otherwise, factors 1000
+ next
+ threshold 0.025pt
+ classes \tightparpassclasses
+ tolerance 300
+ adjustspacing 3
+ adjustspacingstep 1
+ adjustspacingshrink 10
+ adjustspacingstretch 15
+ orphanpenalty 5000
+ next
+ threshold 0.025pt
+ tolerance 350
+ adjustspacing 3
+ adjustspacingstep 1
+ adjustspacingshrink 20
+ adjustspacingstretch 40
+ orphanpenalty 5000
+ emergencystretch .25\bodyfontsize
+ % whatever
+ next
+ threshold 0.025pt
+ tolerance 3000
+ orphanpenalty 5000
+ emergencystretch .25\bodyfontsize
+\relax
+\stoptyping
+
+With \typ {ifadjustspacing} you ignore steps that expect the font to be setup, so
+you don't waste time if that is not the case.
+
+There is also a \typ {callback} parameter but that one is experimental and used
+for special purposes and testing. We don't expect users to mess with that.
+
+A really special feature is optional content. Here we use as example a quote from
+Digital Typography:
+
+\starttyping[paragraph=yes,align=flushleft]
+Many readers will skim over formulas on their first reading
+of your exposition. Therefore, your sentences should flow
+smoothly when all but the simplest formulas are replaced by
+\quotation {blah} or some other \optionalword {1} {grunting }noise.
+\stoptyping
+
+Here the \type {grunting} (with embedded space) is considered optional. When you
+set \typ {\linebreakoptional} to~1 this word will be typeset. However, when you
+set the pass parameter \typ {linebreakoptional} to~0 it will be skipped. There
+can be multiple optional words with different numbers. The numbers are actually
+bits in a bit set so plenty is possible. However, normally these two values are
+enough, if used at all.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Definitions]
+
+The description above is rather low level and in practice users will use a bit
+higher level interface. Also, in practice only a subset of the parameters makes
+sense in general usage. It is not that easy to decide on what parameter subset
+will work out well but it can be fun to play with variants. After all, this is
+also what \TEX\ is about: look, feel and fun.
+
+Some users praise the ability of recent \TEX\ engines to provide expansion and
+protrusion. This feature is a bit demanding because not only does it add to
+runtime (although in \LUAMETATEX\ that normally can be neglected), it also makes
+the output files larger. Some find it hard to admit, but it even can result in
+bad looking documents when applied with extremes.
+
+The traditional (\MKIV) way to set up expansion is to add this to the top of the
+document, or at least before fonts get loaded.
+
+\startbuffer[pass-a]
+\definefontfeature
+ [default]
+ [default]
+ [expansion=quality,protrusion=quality]
+\stopbuffer
+
+\typebuffer[a]
+
+and later on to enable it with:
+
+\starttyping
+\setupalign[hz]
+\stoptyping
+
+However, par passes make it possible to be more selective. Take the following two
+definitions:
+
+\startbuffer[pass-b]
+\startsetups align:pass:quality:1
+ \pretolerance 50
+ \tolerance 150
+ \parpasses 6
+ identifier \parpassidentifier{quality:1}
+ threshold 0.025pt
+ tolerance 175
+ next
+ threshold 0.025pt
+ tolerance 200
+ next
+ threshold 0.025pt
+ tolerance 250
+ next
+ classes \almostdecentparpassclasses
+ tolerance 300
+ emergencystretch .25\bodyfontsize
+ next ifadjustspacing
+ classes \indecentparpassclasses
+ tolerance 300
+ adjustspacing 3
+ emergencystretch .25\bodyfontsize
+ next
+ threshold 0.025pt
+ tolerance 3000
+ emergencystretch 2\bodyfontsize
+ \relax
+\stopsetups
+
+\startsetups align:pass:quality:2
+ \pretolerance 50
+ \tolerance 150
+ \parpasses 5
+ identifier \parpassidentifier{quality:2}
+ threshold 0.025pt
+ tolerance 175
+ next
+ threshold 0.025pt
+ tolerance 200
+ next
+ threshold 0.025pt
+ tolerance 250
+ next ifadjustspacing
+ classes \indecentparpassclasses
+ tolerance 300
+ adjustspacing 3
+ emergencystretch .25\bodyfontsize
+ next
+ threshold 0.025pt
+ tolerance 3000
+ emergencystretch 2\bodyfontsize
+ \relax
+\stopsetups
+\stopbuffer
+
+\typebuffer[pass-b]
+
+You can now enable one of these:
+
+\starttyping
+\setupalignpass[quality:1]
+\stoptyping
+
+\startbuffer[pass-c]
+\starttext
+ \showmakeup[expansion,space]
+ \startTEXpage[offset=1ts]
+ \startcombination[3*3]
+ {\vtop{\hsize 8cm\setupalignpass[none] \samplefile{tufte}}} {none}
+ {\vtop{\hsize 9cm\setupalignpass[none] \samplefile{tufte}}} {none}
+ {\vtop{\hsize12cm\setupalignpass[none] \samplefile{tufte}}} {none}
+ {\vtop{\hsize 8cm\setupalignpass[quality:1]\samplefile{tufte}}} {quality:1}
+ {\vtop{\hsize 9cm\setupalignpass[quality:1]\samplefile{tufte}}} {quality:1}
+ {\vtop{\hsize12cm\setupalignpass[quality:1]\samplefile{tufte}}} {quality:1}
+ {\vtop{\hsize 8cm\setupalignpass[quality:2]\samplefile{tufte}}} {quality:2}
+ {\vtop{\hsize 9cm\setupalignpass[quality:2]\samplefile{tufte}}} {quality:2}
+ {\vtop{\hsize12cm\setupalignpass[quality:2]\samplefile{tufte}}} {quality:2}
+ \stopcombination
+ \stopTEXpage
+\stoptext
+\stopbuffer
+
+The result is shown in \in {figure} [fig:passes:expansion] where you can see that
+expansion is applied selectively; you have to zoom in to see where.
+
+\startplacefigure[location=page,reference=fig:passes:expansion,title={Two different passes applied to \type {tufte.tex}.}]
+ \typesetbuffer[pass-a,pass-b,pass-c][width=\textwidth]
+\stopplacefigure
+
+\stopsectionlevel
+
+\startsectionlevel[title=Tracing]
+
+There are several ways to see what goes on. The engine has a tracing option that
+is set with \type {\tracingpasses}. Setting it to \type {1} reports the passes on
+the console, and a value of \type {2} also gives some details.
+
+There is a also a tracker, \type {paragraphs.passes} that can be enabled. This gives
+a bit more information:
+
+\starttyping
+\enabletrackers[paragraphs.passes]
+\enabletrackers[paragraphs.passes=summary]
+\enabletrackers[paragraphs.passes=details]
+\stoptyping
+
+If you want to see where expansion kicks in, you can use:
+
+\starttyping
+\showmakeup[expansion]
+\stoptyping
+
+This is just one of the options, \type {spaces}, \type {penalties}, \type {glue}
+are are useful when you play with passes, but if you are really into the low level
+details, this is what you want:
+
+\startbuffer
+\startnarrower[5*right]
+\startshowbreakpoints[option=margin,offset=\dimexpr{.5\emwidth-\rightskip}]
+\samplefile{tufte}
+\stopshowbreakpoints
+\stopnarrower
+\stopbuffer
+
+\typebuffer \getbuffer
+
+You can see the chosen solutions with
+
+\startbuffer
+\showbreakpoints[n=1]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+When we started playing with the par builder in the perspective of
+math, we side tracked and ended up with a feature that can ge used
+in controlled situations. Currently we only have a low level
+\CONTEXT\ interface for this (see \in {figure} [fig:passes:lousiness]).
+
+\startbuffer[lousiness]
+ \startTEXpage[offset=1ts]
+ \startcombination[3*1]
+ \bgroup \vtop\bgroup
+ \hsize8cm
+ \setupalign[verytolerant]
+ \tracinglousiness 1
+ \lousiness 0
+ \samplefile{ward}
+ \egroup \egroup
+ {\type {\tracinglousiness 1}
+ \type {\lousiness 0}}
+ \bgroup \vtop\bgroup
+ \hsize8cm
+ \setupalign[verytolerant]
+ \lousiness 1 11 0
+ \samplefile{ward}
+ \egroup \egroup
+ {\type {\lousiness 1 11 0}}
+ \bgroup \vtop\bgroup
+ \hsize8cm
+ \setupalign[verytolerant]
+ \silliness 11
+ \samplefile{ward}
+ \egroup \egroup
+ {\type {\silliness 11}}
+ \stopcombination
+\stopTEXpage
+\stopbuffer
+
+\startplacefigure[location=here,reference=fig:passes:lousiness,title={Influencing the way \TEX\ breaks lines applied to \type {ward.tex}.}]
+ \typesetbuffer[lousiness][width=\textwidth]
+\stopplacefigure
+
+\stopsectionlevel
+
+\startsectionlevel[title=Criterion]
+
+The \type {granular} alignment option will configure the linebreakcriterion to
+work with $0.25$ steps instead of $0.50$ steps which means that successive lines
+can become a bit closer in spacing. There is no real impact on performance
+because testing happens anyway. In \in {figure}[fig:criterion] you see some
+examples, where in some it indeed makes a difference.
+
+\startbuffer[criterion]
+\starttext
+\definecolor[ttest][a=1,t=.5]
+\definecolor[rtest][a=1,t=.5,r=1]
+\dostepwiserecurse{80}{120}{1}{
+ \startTEXpage[offset=1ts]
+ \startcombination[3*1]
+ {\startoverlay
+ {\vtop{\showmakeup[space]\hsize #1mm\ttest \samplefile{tufte}}}
+ {\vtop{\showmakeup[space]\hsize #1mm\rtest \setupalign[granular]\samplefile{tufte}}}
+ \stopoverlay} {}
+ {\vtop{\showmakeup[space]\hsize #1mm\ttest \samplefile{tufte}}} {}
+ {\vtop{\showmakeup[space]\hsize #1mm\rtest \setupalign[granular]\samplefile{tufte}}} {}
+ \stopcombination
+ \stopTEXpage
+}
+\stoptext
+\stopbuffer
+
+\startplacefigure[location=here,reference=fig:criterion,title={More granular interline criteria.}]
+ \startcombination[1*4]
+ {\typesetbuffer[criterion][width=\textwidth,page=35]} {}
+ {\typesetbuffer[criterion][width=\textwidth,page=36]} {}
+ {\typesetbuffer[criterion][width=\textwidth,page=37]} {}
+ {\typesetbuffer[criterion][width=\textwidth,page=38]} {}
+ \stopcombination
+\stopplacefigure
+
+\stopsectionlevel
+
+\startsectionlevel[title=Examples]
+
+\start \em
+
+ The \CONTEXT\ distribution comes with a few test setups: \typ
+ {spac-imp-tests.mkxl}. Once we have found a suitable set of values and sample
+ texts we might discuss them here.
+
+ Currently we provide the following predefined passes that you can enable with
+ \typ {\setupalignpass}: \type {decent}, \type {quality}, \type {test1}, \type
+ {test2}, \type {test3}, \type {test4}, \type {test5}. We hope that users are
+ willing to test these.
+
+\stop
+
+\stopsectionlevel
+
+\startsectionlevel[title=Pages]
+
+While the par builder does multiple passes, the page builder is a single pass
+progressive routine. Every time something gets added to the (so called) main
+vertical list the page state gets updated and when the page overflows what has
+been collected gets passed to the output routine. It is to a large extend driven
+by glue (with stretch and shrink) and penalties and when content (boxes) is added
+the process is somewhat complicated by inserts as these needs to be taken into
+account too.
+
+You can get pages that run from top to bottom by adding stretch between lines but
+by default in \CONTEXT\ we prefer to fill up the bottom with white space.
+
+It can be hard to make decisions at the \TEX\ end around a potential page break
+because in order to get an idea how much space is left, one needs to trigger the
+page builder which can have side effects.
+
+Penalties play an important role and because these are used to control for
+instance widows and clubs high values can lead to underfull pages so if we want
+to influence that we need to cheat. For this we have three experimental
+mechanisms:
+
+\startitemize[packed]
+\startitem tweaking the page goal: \type {\pageextragoal} \stopitem
+\startitem initializing the state quantities: \type {\initialpageskip} \stopitem
+\startitem adapting the state quantities as we go: \type {\additionalpageskip} \stopitem
+\stopitemize
+
+The first tweak is for me to play with, and when a widow or club is seen the
+extra amount can kick in. This feature is likely to be replaced by a more
+configurable one.
+
+The second tweak lets the empty page start out with some given height, stretch
+and shrink. This variable is persistent over pages. This is not true for the
+third tweak: it kicks in when the page gets initialized {\em or} as we go, but
+after it has been applied the value is reset. That makes it a feature like \type
+{\looseness}. We could combine these into one (because one can set up a
+persistent one in the macro package at well defined spots) but having an initial
+one also nicely can compensate the usual topskip glue hackery with a more natural
+control option.
+
+\startbuffer[pagelooseness-1]
+\starttext
+ \showframe[text]
+ \setuplayout[width=middle,headerdistance=5mm]
+ \setupalign[vertical,height]
+ \dorecurse{10}{
+ \samplefile{tufte}\par
+ \setpagelooseness[lines=2]%
+ \dorecurse{5}{
+ {\red \samplefile{knuth}}\par
+ {\green \samplefile {ward}}\par
+ {\blue \samplefile{davis}}\par
+ }
+ \page
+ }
+\stoptext
+\stopbuffer
+
+\startbuffer[pagelooseness-2]
+\starttext
+ \showframe[text]
+ \setuplayout[width=middle,headerdistance=5mm]
+ \setupalign[vertical,height]
+ \dorecurse{10}{
+ \samplefile{tufte}\par
+ \setpagelooseness[-3]%
+ \dorecurse{5}{
+ {\red \samplefile{knuth}}\par
+ {\green \samplefile {ward}}\par
+ {\blue \samplefile{davis}}\par
+ }
+ \page
+ }
+\stoptext
+\stopbuffer
+
+Adapting the layout (within the regular text area) is done with \typ
+{\setpagelooseness} an demonstrated in \in {figure} [fig:pagelooseness-1] and \in
+{figure} [fig:pagelooseness-2]. Possible parameters are \type {lines}, \type
+{height}, \type {stretch} and \type {shrink}. You can also directly specify the
+number of lines. The other two features are not (yet) interfaced.
+
+\startplacefigure[location=here,reference=fig:pagelooseness-1,title={Cheating with page dimensions: \type {[lines=2]}.}]
+ \startcombination[4*1]
+ {\typesetbuffer[pagelooseness-1][width=\combinationwidth,page=1,frame=on]} {}
+ {\typesetbuffer[pagelooseness-1][width=\combinationwidth,page=2,frame=on]} {}
+ {\typesetbuffer[pagelooseness-1][width=\combinationwidth,page=3,frame=on]} {}
+ {\typesetbuffer[pagelooseness-1][width=\combinationwidth,page=4,frame=on]} {}
+ \stopcombination
+\stopplacefigure
+
+\startplacefigure[location=here,reference=fig:pagelooseness-2,title={Cheating with page dimensions: \type {[-3]}.}]
+ \startcombination[4*1]
+ {\typesetbuffer[pagelooseness-2][width=\combinationwidth,page=1,frame=on]} {}
+ {\typesetbuffer[pagelooseness-2][width=\combinationwidth,page=2,frame=on]} {}
+ {\typesetbuffer[pagelooseness-2][width=\combinationwidth,page=3,frame=on]} {}
+ {\typesetbuffer[pagelooseness-2][width=\combinationwidth,page=4,frame=on]} {}
+ \stopcombination
+\stopplacefigure
+
+It is not that trivial to fulfill the wide range of user demands but over time
+the \typ {\setupalign} commands has gotten plenty of features. Getting for
+instance windows and clubs right in the kind of mixed usage that is common in
+\CONTEXT\ is not always easy. One can experiment with scenarios (also to get some
+understanding of matters) but none is probably perfect (unless one does something
+close to manual tweaking). There is also the butterfly effect: a change here
+might trigger na issue there.
+
+The examples in \in {figure} [fig:vz-1], \in [fig:vz-2] and \in [fig:vz-3] scale
+vertically in order ti fill up the text area; the \type {vz} parameter is set
+with \typ {setuplayout}. In the example the widow and club penalties are set to
+$10000$. In these examples we have enabled the \typ {layout.vz} trackers that
+shows a small black rule indicating the amount of stretch.
+
+\startbuffer[vz-1]
+\starttext
+ \showframe[text]
+ \enabletrackers[layout.vz]
+ \setuplayout[width=middle,headerdistance=5mm,vz=no]
+ \clubpenalty 10000
+ \widowpenalty 10000
+ \dostepwiserecurse{0}{30}{1}{
+ \dorecurse{#1}{\strut dummy line ##1\par}
+ \dorecurse{4}{\samplefile{tufte}\par}
+ }
+\stoptext
+\stopbuffer
+
+\startbuffer[vz-2]
+\starttext
+ \showframe[text]
+ \enabletrackers[layout.vz]
+ \setuplayout[width=middle,headerdistance=5mm,vz=yes]
+ \clubpenalty 10000
+ \widowpenalty 10000
+ \dostepwiserecurse{0}{30}{1}{
+ \dorecurse{#1}{\strut dummy line ##1\par}
+ \dorecurse{4}{\samplefile{tufte}\par}
+ }
+\stoptext
+\stopbuffer
+
+\startbuffer[vz-3]
+\starttext
+ \showframe[text]
+ \enabletrackers[layout.vz]
+ \setuplayout[width=middle,headerdistance=5mm,vz=2]
+ \clubpenalty 10000
+ \widowpenalty 10000
+ \dostepwiserecurse{0}{30}{1}{
+ \dorecurse{#1}{\strut dummy line ##1\par}
+ \dorecurse{4}{\samplefile{tufte}\par}
+ }
+\stoptext
+\stopbuffer
+
+\startplacefigure[location=here,reference=fig:vz-1,title={Cheating with vertical expansion: \type {[vz=no]}.}]
+ \startcombination[4*1]
+ {\typesetbuffer[vz-1][width=\combinationwidth,page=1,frame=on]} {}
+ {\typesetbuffer[vz-1][width=\combinationwidth,page=2,frame=on]} {}
+ {\typesetbuffer[vz-1][width=\combinationwidth,page=3,frame=on]} {}
+ {\typesetbuffer[vz-1][width=\combinationwidth,page=4,frame=on]} {}
+ \stopcombination
+\stopplacefigure
+
+\startplacefigure[location=here,reference=fig:vz-2,title={Cheating with vertical expansion: \type {[vz=yes]}.}]
+ \startcombination[4*1]
+ {\typesetbuffer[vz-2][width=\combinationwidth,page=1,frame=on]} {}
+ {\typesetbuffer[vz-2][width=\combinationwidth,page=2,frame=on]} {}
+ {\typesetbuffer[vz-2][width=\combinationwidth,page=3,frame=on]} {}
+ {\typesetbuffer[vz-2][width=\combinationwidth,page=4,frame=on]} {}
+ \stopcombination
+\stopplacefigure
+
+\startplacefigure[location=here,reference=fig:vz-3,title={Cheating with vertical expansion: \type {[vz=2]}.}]
+ \startcombination[4*1]
+ {\typesetbuffer[vz-3][width=\combinationwidth,page=1,frame=on]} {}
+ {\typesetbuffer[vz-3][width=\combinationwidth,page=2,frame=on]} {}
+ {\typesetbuffer[vz-3][width=\combinationwidth,page=3,frame=on]} {}
+ {\typesetbuffer[vz-3][width=\combinationwidth,page=4,frame=on]} {}
+ \stopcombination
+\stopplacefigure
+
+There are a few other tweaks but these one can wonder about these. We can add
+stretch and shrink to the baseline skip, something that can also be triggered
+with the \quote {spread} option to \typ {\setupalign}, assuming that also \typ
+{height} is given). An alternative is to permit an extra line and accept a visual
+overflow, assuming that the layout is set up to make sure that the footer line
+doesn't overlap. None of this guarantees that a whole document with plenty of
+graphics and special constructs will come out well, but for text only it might
+work okay. \in {Figures} [fig:extra-1], \in [fig:extra-2] and \in [fig:extra-3]
+show some of this.
+
+\startbuffer[extra-1]
+\starttext
+ \showframe[text]
+ \setuplayout[width=middle,headerdistance=15mm,vz=no]
+ \setupalign[height]
+ \clubpenalty 10000
+ \widowpenalty 10000
+ \dorecurse{10}{
+ \samplefile{tufte}\par
+ \samplefile{knuth}\par
+ \samplefile{ward}\par
+ \samplefile{davis}\par
+ }
+\stoptext
+\stopbuffer
+
+\startbuffer[extra-2]
+\starttext
+ \showframe[text]
+ \setuplayout[width=middle,headerdistance=15mm,vz=no]
+ \setupalign[height]
+ \clubpenalty 10000
+ \widowpenalty 10000
+ \baselineskip 1\baselineskip plus 1pt minus .1pt
+ \dorecurse{10}{
+ \samplefile{tufte}\par
+ \samplefile{knuth}\par
+ \samplefile{ward}\par
+ \samplefile{davis}\par
+ }
+\stoptext
+\stopbuffer
+
+\startbuffer[extra-3]
+\starttext
+ \showframe[text]
+ \setuplayout[width=middle,headerdistance=15mm,vz=no]
+ \setupalign[height]
+ \clubpenalty 10000
+ \widowpenalty 10000
+ \pageextragoal1\lineheight
+ \dorecurse{10}{
+ \samplefile{tufte}\par
+ \samplefile{knuth}\par
+ \samplefile{ward}\par
+ \samplefile{davis}\par
+ }
+\stoptext
+\stopbuffer
+
+\page
+
+\startplacefigure[location=here,reference=fig:extra-1,title={Cheating: just high penalties.}]
+ \startcombination[4*2]
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-1][width=\combinationwidth,page=1,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-1][width=\combinationwidth,page=2,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-1][width=\combinationwidth,page=3,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-1][width=\combinationwidth,page=4,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-1][width=\combinationwidth,page=5,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-1][width=\combinationwidth,page=6,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-1][width=\combinationwidth,page=7,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-1][width=\combinationwidth,page=8,frame=on]}} {}
+ \stopcombination
+\stopplacefigure
+
+\startplacefigure[location=here,reference=fig:extra-2,title={Cheating: \typ {\baselineskip 1\baselineskip plus 1pt minus .1pt}.}]
+ \startcombination[4*2]
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-2][width=\combinationwidth,page=1,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-2][width=\combinationwidth,page=2,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-2][width=\combinationwidth,page=3,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-2][width=\combinationwidth,page=4,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-2][width=\combinationwidth,page=5,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-2][width=\combinationwidth,page=6,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-2][width=\combinationwidth,page=7,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-2][width=\combinationwidth,page=8,frame=on]}} {}
+ \stopcombination
+\stopplacefigure
+
+\startplacefigure[location=here,reference=fig:extra-3,title={Cheating: \typ {\pageextragoal \lineheight}.}]
+ \startcombination[4*2]
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-3][width=\combinationwidth,page=1,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-3][width=\combinationwidth,page=2,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-3][width=\combinationwidth,page=3,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-3][width=\combinationwidth,page=4,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-3][width=\combinationwidth,page=5,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-3][width=\combinationwidth,page=6,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-3][width=\combinationwidth,page=7,frame=on]}} {}
+ {\clip[ny=12,sy=1,y=10]{\typesetbuffer[extra-3][width=\combinationwidth,page=8,frame=on]}} {}
+ \stopcombination
+\stopplacefigure
+
+\stopsectionlevel
+
+\startsectionlevel[title=Profiles]
+
+You can have a paragraph with lines that exceed the maximum height and/or depth
+or where spaces end up in a way that create so called rivers. Rivers are more a
+curiosity than an annoyance because any attempt to avoid them is likely to result
+in a worse looking result. The unequal line distances can be annoying too but
+these can be avoided when bringing lines closer together doesn't lead to clashes.
+This can be done without reformatting the paragraph by passing the \type
+{profile} option to \typ {\setupalign}. It comes at the cost of a little more
+runtime and (as far as we observed) it kicks in seldom, for instance when inline
+math is used that has super- or subscripts, radicals, fractions or other slightly
+higher constructs.
+
+\stopsectionlevel
+
+\page % colofon after flushed page float
+
+\stopdocument
+
+% \showmakeup[glue]
+
+% \startsetups align:pass:whatever
+% \pretolerance 75
+% \tolerance 150
+% \parpasses 3
+% threshold 0.025pt
+% classes \indecentparpassclasses
+% tolerance 150
+% next
+% threshold 0.025pt
+% classes \indecentparpassclasses
+% tolerance 200
+% emergencystretch .25\bodyfontsize
+% next
+% threshold 0.025pt
+% classes \indecentparpassclasses
+% tolerance 200
+% optional 1
+% emergencystretch .5\bodyfontsize
+% \relax
+% \linebreakpasses\plusone
+% \stopsetups
+
+
+% \dostepwiserecurse{80}{120}{2} {
+% \start
+% \hsize#1mm \getbuffer \getbuffer \blank
+% \hsize#1mm \setupalignpass[whatever] \getbuffer \getbuffer \page
+% \stop
+% }
+
+% discuss the disc options options pre, post orphaned, penalties (or maybe in a new
+% lowlevel-discretionaries)
+
+% \starttext
+% \showmakeup[line]
+% % \discretionaryoptions\zerocount
+% % \discretionaryoptions\prefernobreakdiscoptioncode
+% \hsize\widthofstring{sciencefiction}
+% science\discretionary{\red fict-}{\green ion}{\blue fiction}\par
+% science\discretionary{\red f\kern0ptiction}{}{\blue fiction}\par
+% science\-fiction\par
+% science\discretionary{-}{}{\blue fiction}\par
+% \hyphenation{science-fiction}
+% sciencefiction\par
+% \stoptext
+
+% optional content example (todo: show break and nobreak keywords):
+
+% \start
+% \tttf
+% \hsize\widthofstring{short}
+% --:\par
+% \discretionaryoptions\zerocount
+% \discretionary{before}{after}{short}\par
+% \discretionary{before}{}{short}\blank
+% nb:\par
+% \discretionaryoptions\prefernobreakdiscoptioncode
+% \discretionary{before}{after}{short}\par
+% \discretionary{before}{}{short}\blank
+% br:\par
+% \discretionaryoptions\preferbreakdiscoptioncode
+% \discretionary{before}{after}{short}\par
+% \discretionary{before}{}{short}\blank
+% \stop
+
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-loops.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-loops.tex
index 30a3ef64cfb..cf7ab7706c3 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-loops.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-loops.tex
@@ -324,4 +324,95 @@ So:
\stopsectionlevel
+\startsectionlevel[title=About quitting]
+
+You can quit a local and expanded loop at the next iteration using \typ
+{\quitloop}. With \typ {\quitloopnow} you immediately leave the loop but you
+need to beware of side effects, like not ending a condition properly. Keep in
+mind that a macro language like \TEX\ is not that friendly towards loops so the
+implementation is a bit hairy.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Simple repeaters]
+
+For simple iterations we have \typ {\localcontrolledrepeat}, \typ
+{\expandedrepeat}, \typ {\unexpandedrepeat}. These take one integer instead of
+three: the final iterator value.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Endless loops]
+
+There are three endless loop primitives: \typ {\localcontrolledendless}, \typ
+{\expandedendless}, \typ {\unexpandedendless}. These will keep running till you
+quit them. The loop counter can overflow the maximum integer value and will then
+start again at 1.
+
+\stopsectionlevel
+
+
+\startsectionlevel[title=Loop variables]
+
+The following example shows how we can access the current, parent and grand parent
+loop iterator values using a parameter like syntax:
+
+\startbuffer
+\localcontrolledloop 1 4 1 {%
+ \localcontrolledloop 1 3 1 {%
+ \localcontrolledloop 1 2 1 {%
+ \edef\foo{[#G,#P,#I]}\foo
+ \def \oof{<#G,#P,#I>}\oof
+ (#G,#P,#I)\space
+ }
+ \par
+ }
+}
+\stopbuffer
+
+\typebuffer \startpacked\getbuffer\stoppacked
+
+Another way to access a(ny) parent is:
+
+\starttyping
+\localcontrolledloop 1 4 1 {%
+ \localcontrolledloop 1 3 1 {%
+ \localcontrolledloop 1 2 1 {%
+ (\the\previousloopiterator2,%
+ \the\previousloopiterator1,%
+ \the\currentloopiterator)
+ }
+ \par
+ }
+}
+\stoptyping
+
+These methods make that one doesn't have to store the outer loop variables for
+usage inside the inner loop. Watch out with the \type {\edef}:
+
+\startbuffer
+\edef\foo{[#G,#P,#I]}
+\def \oof{<#G,#P,#I>}
+
+\localcontrolledloop 1 4 1 {%
+ \localcontrolledloop 1 3 1 {%
+ \localcontrolledloop 1 2 1 {%
+ %
+ % I iterator \currentloopiterator
+ % P parent \previousloopiterator1
+ % G grandparent \previousloopiterator2
+ %
+ \edef\ofo{[#G,#P,#I]}%
+ \foo\oof\ofo(#G,#P,#I)\space
+ %
+ }
+ \par
+ }
+}
+\stopbuffer
+
+\typebuffer \startpacked\getbuffer\stoppacked
+
+\stopsectionlevel
+
\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
index 83e43818f08..9557a7299da 100644
--- 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
@@ -11,10 +11,10 @@
% 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]
+\usemodule[system-syntax]
\environment lowlevel-style
@@ -991,6 +991,522 @@ in turn only needs incrementing a reference counter.
\stopsectionlevel
+\startsectionlevel[title=Passing parameters]
+
+When you define a macro, the \type {#1} and more parameters are embedded as a
+reference to a parameter that is passed. When we have four parameters, the
+parameter stack has four entries and when an entry is eventually accessed a new
+input level is pushed and tokens are fetched from that list. This has some side
+effects when we check a parameter. This can happen multiple times, depending on
+how often we access a parameter. Take the following:
+
+\startbuffer
+\def\oof#1{#1}
+
+\tolerant\def\foo[#1]#*[#2]%
+ {1:\ifparameter#1\or Y\else N\fi\quad
+ 2:\ifparameter#2\or Y\else N\fi\quad
+ \oof{3:\ifparameter #1\or Y\else N\fi\quad
+ 4:\ifparameter #2\or Y\else N\fi\quad}%
+ \par}
+
+\foo \foo[] \foo[][] \foo[A] \foo[A][B]
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+\startpacked \tttf
+\inlinebuffer
+\stoppacked
+
+as you probably expect. However the first two checks are different from the
+embedded checks because they can check against the parameter reference. When we
+expand \type {\oof} its argument gets passed to the macro as a list and when the
+scanner collects the next token it will then push the parameter content on the
+input stack. So, then, instead of a reference we get the referenced parameter
+list. Internally that means that in 3 and 4 we check for a token and not for the
+length of the list (as in case 1 & 2). This means that
+
+\starttyping
+\iftok{#1}\emptytoks Y\else N\fi
+\ifparameter#1\or Y\else N\fi
+\stoptyping
+
+are different. In the first case we have a proper token list and nested
+conditionals in that list are okay. In the second case we just look ahead to see
+if there is an \type {\or}, \type {\else} or other condition related command and
+if so we decide that there is no parameter. So, if \type {\ifparameter} is a
+suitable check for empty depends on the need for expansion.
+
+When you define macros that themselves call macros that should operate on the
+arguments of its parent you can easily pass these:
+
+\startbuffer[test-1]
+\def\foo#1#2%
+ {\oof{#1}{#2}{P}%
+ \oof{#1}{#2}{Q}%
+ \oof{#1}{#2}{R}}
+
+\def\oof#1#2#3%
+ {[#1][#1]%
+ #3%
+ [#2][#2]}
+\stopbuffer
+
+\typebuffer[test-1]
+
+Here the nested call to \type {\oof} involved three passed parameters. You can
+avoid that as follows:
+
+\startbuffer[test-2]
+\def\foo#1#2%
+ {\def\MyIndexOne{#1}%
+ \def\MyIndexTwo{#2}%
+ \oof{P}\oof{Q}\oof{R}}
+
+\def\oof#1%
+ {(\MyIndexOne)(\MyIndexOne)%
+ #1%
+ (\MyIndexTwo)(\MyIndexTwo)}
+\stopbuffer
+
+\typebuffer[test-2]
+
+You can also do this:
+
+\startbuffer[test-3]
+\def\foo#1#2%
+ {\def\oof##1%
+ {/#1/#2/%
+ ##1%
+ /#1//#2/}%
+ \oof{P}\oof{Q}\oof{R}}
+\stopbuffer
+
+\typebuffer[test-3]
+
+These parameters indicated by \type {#} in the macro body are in fact references.
+When we call for instance \type {\foo {1}{2}} the two parameters get pushed on a
+parameter stack and the embodied references point to these stack entries. By the
+time that body gets expanded \TEX\ bumps the input level and pushes the parameter
+list onto the input stack. It then continues expansion. The parameter is not
+copied, because it can't be changed anyway. The only penalty in terms of
+performance and memory usage is the pushing and popping of the input. So how does
+that work out for these three cases?
+
+When in the first case the \type {\oof{#1}{#2}{P}} is seen, \TEX\ starts expanding
+the \type {\oof} macro. That one expects three arguments. The \type {#1} reference is
+seen and in this case a copy of that parameter is passed. The same is true for the
+other two. Then, inside \type {\oof} expansion happens on the parameters on the stack
+and no copies have to be made there.
+
+The second case defines two macros so again two copies are made that make the bodies
+of these macros. This comes at the cost of some runtime and memory. However, this
+time with \type {\oof{P}} only one argument gets passed and instead expansion of the
+macros happen in there.
+
+Normally macro arguments are not that large but there can be situations where we
+really want to avoid useless copying. This not only saves memory but also can give a
+bit better performance. In the examples above the second variant is some 10\percent
+faster than the first one. We can gain another 10\percent with the following trick:
+
+\startbuffer[test-4]
+\def\foo#1#2%
+ {\parameterdef\MyIndexOne\plusone % 1
+ \parameterdef\MyIndexTwo\plustwo % 2
+ \oof{P}\oof{Q}\oof{R}\norelax}
+
+\def\oof#1%
+ {<\MyIndexOne><\MyIndexOne>%
+ #1%
+ <\MyIndexTwo><\MyIndexTwo>}
+\stopbuffer
+
+\typebuffer[test-4]
+
+Here we define an explicit parameter reference that we access later on. There is
+the overhead of a definition but it can be neglected. We use that reference
+(abstraction) in \type {\oof}. Actually you can use that reference in any call
+down the chain.
+
+When applied to \type {\foo{1}{2}} the four variants above give us:
+
+\startpacked
+\startlines \tt
+\getbuffer[test-1]\foo{1}{2}
+\getbuffer[test-2]\foo{1}{2}
+\getbuffer[test-3]\foo{1}{2}
+\getbuffer[test-4]\foo{1}{2}
+\stoplines
+\stoppacked
+
+Before we had \type {parameterdef} we had this:
+
+\startbuffer[test-5]
+\def\foo#1#2%
+ {\integerdef\MyIndexOne\parameterindex\plusone % 1
+ \integerdef\MyIndexTwo\parameterindex\plustwo % 2
+ \oof{P}\oof{Q}\oof{R}\norelax}
+
+\def\oof#1%
+ {<\expandparameter\MyIndexOne><\expandparameter\MyIndexOne>%
+ #1%
+ <\expandparameter\MyIndexTwo><\expandparameter\MyIndexTwo>}
+\stopbuffer
+
+\typebuffer[test-5]
+
+It involves more tokens, is a bit less abstract, but as it is a cheap extension
+we kept it. It actually demonstrates that one can access parameters in the stack
+by index, but it one then needs to keep track of where access takes place. In
+principle one can debug the call chain this way.
+
+To come back to performance and memory usage, when the arguments become larger
+the fourth variant with the \type {\parameterdef} quickly gains over the others.
+But it only shows in exceptional usage. This mechanism is more about abstraction:
+it permits us to efficiently turn arguments into local variables without the
+overhead involved in creating macros.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Nesting]
+
+We also have a few preamble features that relate to nesting. Although we can do
+without (as shown for years in \LMTX) they do have some benefits. They are
+discussed as group here and because they are only useful for low level
+programming we stick to simple examples. The \type {#L} and \type {#R} use the
+following token as delimiters. Here we use \type {[} and \type {]} but they can
+be a \type {\cs} as well. Nested delimiters are handled well.
+
+The \type {#S} grabs the argument till the next final square bracket \type {]}
+but in the process will grab nested with it sees a \type {[}. The \type {#P} does
+the same for parentheses and \type {#X} for angle brackets. In the next examples
+the \type {#*} just gobbles optional spaces but we've seen that one already.
+
+The \type {#G} argument just registers the next token as delimiter but it will
+grab multiple of them. The \type {#M} gobbles more: in addition to the delimiter
+spaces are gobbled.
+
+\startbuffer
+\tolerant\def\fooA [#1]{(#1)}
+\tolerant\def\fooB [#L[#R]#1{(#1)}
+\tolerant\def\fooC #S#1{(#1)}
+\tolerant\def\fooE #S#1,{(#1)}
+\tolerant\def\fooF #S#1#*#S#2{(#1/#2)}
+\tolerant\def\fooG [#1]#S[#2]#*#S[#3]{(#1/#2/#3)}
+\tolerant\def\fooH [#1][#S#2]#*[#S#3]{(#1/#2/#3)}
+\tolerant\def\fooI #1=#2#G,{(#1=#2)}
+\tolerant\def\fooJ #1=#2#M,{(#1=#2)}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\starttabulate[|T|T|T||]
+\NC \type{\fooA [x]} \NC \fooA [x] \NC (x) \NC \NR
+\NC \type{\fooB [x]} \NC \fooB [x] \NC (x) \NC \NR
+\NC \type{\fooC [1[2]3[4]5]} \NC \fooC [1[2]3[4]5] \NC (1[2]3[4]5) \NC \NR
+\NC \type{\fooE X[,]X,} \NC \fooE X[,]X, \NC (X[,]X) \NC \NR
+\NC \type{\fooF [A] [B]} \NC \fooF [A] [B] \NC (A/B) \NC \NR
+\NC \type{\fooF [] []} \NC \fooF [] [] \NC (/) \NC \NR
+\NC \type{\fooG [a][b][c]} \NC \fooG [a][b][c] \NC (a/b/c) \NC \NR
+\NC \type{\fooG [a][b]} \NC \fooG [a][b] \NC (a/b/) \NC \NR
+\NC \type{\fooG [a]} \NC \fooG [a] \NC (a//) \NC \NR
+\NC \type{\fooG [a][x[x]x][c]} \NC \fooG [a][x[x]x][c] \NC (a/x[x]x/c) \NC \NR
+\NC \type{\fooH [a][x[x]x][c]} \NC \fooH [a][x[x]x][c] \NC (a/x[x]x/c) \NC \NR
+\NC \type{\fooI X=X,,,} \NC \fooI X=X,,, \NC (X=X) \NC \NR
+\NC \type{\fooJ X=X, , ,} \NC \fooJ X=X, , , \NC (X=X) \NC \NR
+\stoptabulate
+
+These features make it possible to support nested setups more efficiently and
+also makes it possible to accept values that contain balanced brackets in setup
+commands without additional overhead. Although it has never been an issue to let
+users specify:
+
+\starttyping
+\defineoverlay[whatever][{some \command[withparameters] here}]
+
+\setupfoo[before={\blank[big]}]
+\stoptyping
+
+it might be less confusing to permit:
+
+\starttyping
+\defineoverlay[whatever][some \command[withparameters] here]
+
+\setupfoo[before=\blank[big]]
+\stoptyping
+
+as well, if only because occasionally users get hit by this.
+
+\stopsectionlevel
+
+\startsectionlevel[title=Duplicate hashes]
+
+In \TEX\ every character has a so called category code. Most characters are
+classified as \quote {letter} (they make up words) or as \quote {other}. In
+\UNICODE\ we distinguish symbols, punctuation, and more, but in \TEX\ these are
+all of category \quote {other}. In math however we can classify them differently
+but in this perspective we ignore that. The backslash has category \quote
+{escape} and it starts a control sequence. The curly braces are (internally) of
+category \quote {left brace} and \quote {right brace} aka \quote {begin group}
+and \quote {end group} but, no matter what they are called, they begin and end
+something: a group, argument, token list, box, etc. Any character can have those
+categories. Although it would loook strange to a \TEX\ user, this can be made
+valid:
+
+\startbuffer
+!protected !gdef !weird¶1
+B
+ something: ¶1
+E
+!weird BhereE
+\stopbuffer
+
+\typebuffer
+
+In such a setup spaces can be of category \quote {invisible}. The paragraph
+symbol takes the place of the hash as parameter identifier. The next code shows
+how this is done. Here we wrap all in a macro so that we don't get catcode
+interference in the document source.
+
+\startbuffer[demo]
+\def\NotSoTeX
+ {\begingroup
+ \catcode `B \begingroupcatcode
+ \catcode `E \endgroupcatcode
+ \catcode `¶ \parametercatcode
+ \catcode `! \escapecatcode
+ \catcode 32 \ignorecatcode
+ \catcode 13 \ignorecatcode
+ % this buffer has a definition:
+ \getbuffer
+ % which is now known globally
+ \endgroup}
+\NotSoTeX
+\weird{there}
+\stopbuffer
+
+\typebuffer[demo]
+
+This results in:
+
+\startlines
+\getbuffer [demo]
+\stoplines
+
+In the first line the \type {!}, \type {B} and \type {E} are used as escape and
+argument delimiters, in the second one we use the normal characters. When we show
+the \type {\meaningasis} we get:
+
+\startlines \tt
+\meaningasis\weird
+\stoplines
+
+or in more detail:
+
+\start \tt
+\luatokentable\weird
+\stop
+
+So, no matter how we set up the system, in the end we get some generic
+representation. When we see \type {#1} in \quote {print} it can be either two
+tokens, \type {#} (catcode parameter) followed by \type {1} with catcode other,
+or one token referring to parameter \type {1} where the character \type {1} is
+the opcode of an internal \quote {reference command}. In order to distinguish a
+reference from the two token case, parameter hash tokens get shown as doubles.
+
+\start
+
+\catcode `¶=\parametercatcode
+\catcode `§=\parametercatcode
+
+\startbuffer
+\def\test #1{x#1x##1x####1x}
+\def\tset ¶1{x¶1x¶¶1x¶¶¶¶1x}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+And with \type {\meaning} we get, consistent with the input:
+
+\startlines \tt
+\meaning\test
+\meaning\tset
+\stoplines
+
+These are equivalent, apart from the parameter character in the body of the
+definition:
+
+\startlines \tt
+\luatokentable\test
+\luatokentable\tset
+\stoplines
+
+\stop
+
+Watch how every \quote {parameter} is just a character with the \UNICODE\ index
+of the used input character as property. Let us summarize the process. When a
+single parameter character is seen in the input, the next characer determines how
+it will be interpreted. If there is a digit then it becomes a reference to a
+parameter in the preamble, and when followed by another parameter character it
+will be appended to the body of the macro and that second one is dropped. So, two
+parameter characters become one, and four become two. One parameter character
+becomes a reference and from that you can guess what three in a row become.
+However, when \TEX\ is showing the macro definition (using \type {meaning}) the
+hashes get duplicated in order to distinguish parameter references from parameter
+characters that were kept (e.g.\ for nested definitions). One can make an
+argument for \type {\parameterchar} as we also have \type {\escapechar} but by
+now this convention is settled and it doesn't look that bad anyway.
+
+We now come to the more tricky part with respect to the doubling of hashes. When
+\TEX\ was written its application landscape looked a bit different. For instance,
+fonts were limited and therefore it was natural to access special characters by
+name. Using \type {\#} to get a hash in the text was not that problematic, if one
+needed that character at all. The same can be said for the braces, backslash and
+even the dollar (after all \TEX\ is free software).
+
+But what if we have more visualization and|/|or serialization than meanings and
+tracing? When we opened op the internals in \LUATEX\ and even more in
+\LUAMETATEX\ the duplicating of hashes became a bit of a problem. There we don't
+need to distinguish between a parameter reference and a parameter character
+because by that time these references are resolved. All hashes that we encounter
+are just that: hashes. And this is why in \LUAMETATEX\ we disable the duplication
+for those cases where it serves no purpose.
+
+When the engine scans a macro definition it starts with pickin g up the name of
+the macro. Then it starts scanning the preamble upto the left brace. In the
+preamble of a macro the scanner converts hashes followed by another token into
+single match token. Then when the macro body is scanned single hashes followed by
+a number become a reference, while double hashes become one hash and get
+interpreted at expansion time (possibly triggering an error when not followed by
+a valid specifier like a number). In traditional \TEX\ we basically had this:
+
+\starttyping
+\def\test#1{#1}
+\def\test#1{##}
+\def\test#1{#X}
+\def\test#1{##1}
+\stoptyping
+
+There can be a traling \type {#} in the preamble for special purposes but we
+forget about that now. The first definition is valid, the second definition is
+invalid when the macro is expanded and the third definition triggers an error at
+definition time. The last definition will again trigger an error at expansion
+time.
+
+However, in \LUAMETATEX\ we have an extended preamble where the following
+preamble parameters are handled (some only in tolerant mode):
+
+\starttabulate[|c|||]
+\NC \type{#n} \NC parameter \NC index \type{1} upto \type{E} \NC \NR
+\TB
+\NC \type{#0} \NC throw away parameter \NC increment index \NC \NR
+\NC \type{#-} \NC ignore parameter \NC keep index \NC \NR
+\TB
+\NC \type{#*} \NC gobble white space \NC \NC \NR
+\NC \type{#+} \NC keep (honor) the braces \NC \NC \NR
+\NC \type{#.} \NC ignore pars and spaces \NC \NC \NR
+\NC \type{#,} \NC push back space when no match \NC \NC \NR
+\NC \type{#/} \NC remove leading and trailing spaces and pars \NC \NC \NR
+\NC \type{#=} \NC braces are mandate \NC \NC \NR
+\NC \type{#^} \NC keep leading spaces \NC \NC \NR
+\NC \type{#_} \NC braces are mandate and kept (obey) \NC \NC \NR
+\TB
+\NC \type{#@} \NC par delimiter \NC only for internal usage \NC \NR
+\TB
+\NC \type{#:} \NC pick up scanning here \NC \NC \NR
+\NC \type{#;} \NC quit scanning \NC \NC \NR
+\TB
+\NC \type{#L} \NC left delimiter token \NC followed by token \NC \NR
+\NC \type{#R} \NC right delimiter token \NC followed by token \NC \NR
+\TB
+\NC \type{#G} \NC gobble token \NC followed by token \NC \NR
+\NC \type{#M} \NC gobble token and spaces \NC followed by token \NC \NR
+\TB
+\NC \type{#S} \NC nest square brackets \NC only inner pairs \NC \NR
+\NC \type{#X} \NC nest angle brackets \NC only inner pairs \NC \NR
+\NC \type{#P} \NC nest parentheses \NC only inner pairs \NC \NR
+\stoptabulate
+
+As mentioned these will become so called match tokens and only when we show the
+meaning the hash will show up again.
+
+\startbuffer
+\def\test[#1]#*[*S#2]{.#1.#2.}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlines \tt
+\luatokentable\test
+\stoplines
+
+This means that in the body of a macro you will not see \type {#*} show up. It is
+just a directive that tells the macro parser that spaces are to be skipped. The
+\type {#S} directive makes the parser for the second parameter handle nested
+square bracket. The only hash that we can see end up in the body is the one that
+we entered as double hash (then turned single) followed by (in traditional terms)
+a number that when all gets parsed with then become a reference: the sequence
+\type {##1} internally is \type {#1} and becomes \quote {reference to parameter
+1} assuming that we define a macro in that body. If no number is there, an error
+is issued. This opens up the possibility to add more variants because it will
+only break compatibility with respect to what is seen as error. As with the
+preamble extensions, old documents that have them would have crashed before they
+became available.
+
+So, this means that in the body, and actually anywhere in the document apart from
+preambles, we now support the following general parameter specifiers. Keep in
+mind that they expand in an expansion context which can be tricky when they
+overlap with preamble entries, like for instance \type {#R} in such an expansion.
+Future extensions can add more so {\em any} hashed shortcut is sensitive for
+that.
+
+\starttabulate[|l|||]
+\NC \type{#I} \NC current iterator \NC \type {\currentloopiterator} \NC \NR
+\NC \type{#P} \NC parent iterator \NC \type {\previousloopiterator 1} \NC \NR
+\NC \type{#G} \NC grandparent iterator \NC \type {\previousloopiterator 2} \NC \NR
+\TB
+\NC \type{#H} \NC hash escape \NC \type {#} \NC \NR
+\NC \type{#S} \NC space escape \NC \ruledhbox to \interwordspace{\novrule height .8\strutht} \NC \NR
+\NC \type{#T} \NC tab escape \NC \type {\t} \NC \NR
+\NC \type{#L} \NC newline escape \NC \type {\n} \NC \NR
+\NC \type{#R} \NC return escape \NC \type {\r} \NC \NR
+\NC \type{#X} \NC backslash escape \NC \tex {} \NC \NR
+\TB
+\NC \type{#N} \NC nbsp \NC \type {U+00A0} (under consideration) \NC \NR
+\NC \type{#Z} \NC zws \NC \type {U+200B} (under consideration) \NC \NR
+%NC \type{#-} \NC zwnj \NC \type {U+200C} (under consideration) \NC \NR
+%NC \type{#+} \NC zwj \NC \type {U+200D} (under consideration) \NC \NR
+%NC \type{#>} \NC l2r \NC \type {U+200E} (under consideration) \NC \NR
+%NC \type{#<} \NC r2l \NC \type {U+200F} (under consideration) \NC \NR
+\stoptabulate
+
+Some will now argue that we already have \type {^^} escapes in \TEX\ and \type
+{^^^^} and \type {^^^^^^} in \LUATEX\ and that is true. However, these can be
+disabled, and in \CONTEXT\ they are, where we instead enable the prescript,
+postscript, and index features in mathmode and there type {^} and \type {_} are
+used. Even more: in \CONTEXT\ we just let \type {^}, \type {_} and \type {&} be
+what they are. Occasionally I consider \type {$} to be just that but as I don't
+have dollars I will happily leave that for inline math. When users are not
+defining macros or are using the alternative definitions we can consider making
+the \type {#} a hash. An excellent discussion of how \TEX\ reads it's input and
+changes state accordingly can be found in Victor Eijkhouts \quotation {\TEX\ By
+Topic}, section 2.6: when \type {^^} is followed by a character with $v < 128$
+the interpreter will inject a character with code $v - 64$. When followed by two
+(!) lowercase hexadecimal characters, the corresponding character will be
+injected. Anyway, it not only looks kind of ugly, it also is somewhat weird
+because what follows is interpreted mixed way. The substitution happens early on
+(which is okay). But, how about the output? Traditional \TEX\ serializes special
+characters with a similar syntax but that has become optional when eight bit mode
+was added to the engines, it is configurable in \LUATEX\ and has been dropped in
+\LUAMETATEX: we operate in a \UTF\ universum.
+
+\stopsectionlevel
+
\stopdocument
% freezing pitfalls:
@@ -1010,3 +1526,15 @@ in turn only needs incrementing a reference counter.
% \defcsname
% \edefcsname
% \letcsname
+
+% {
+% \scratchdimenone 10pt \the\currentstacksize\par
+% \scratchdimentwo 10pt \the\currentstacksize\par
+% \scratchdimenone 20pt \the\currentstacksize\par
+% \scratchdimentwo 20pt \the\currentstacksize\par
+% \scratchdimenone 10pt \the\currentstacksize\par
+% {
+% \scratchdimenone 10pt \the\currentstacksize\par
+% \scratchdimentwo 20pt \the\currentstacksize\par
+% }
+% }
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
index 6543c079591..3412a740f5b 100644
--- 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
@@ -1247,7 +1247,7 @@ that a negative depth of more than 1000 point made no sense at all. The last
depth on a vertical list is registered in the \type {\prevdepth} variable. This
is basically a reference into the current list. In order to illustrate some
interesting side effects of setting this \type {\prevdepth} and especially when
-we set it to -1000pt. In order to illustrate this this special value can be set
+we set it to $\tf -1000pt$. In order to illustrate this this special value can be set
to a different value in \LUAMETATEX. However, as dealing with the property is
somewhat special in the engine you should not set it unless you know that the
macro package is ware of it.
@@ -1307,21 +1307,23 @@ coded dimension. We now give a more extensive example:
\egroup
\stopbuffer
-In this example we set \type {\ignoredepthcriterium} to $\tf-50.0pt$ instead of the
+\typebuffer[example][option=TEX]
+
+In this example we set \type {\ignoredepthcriterium} to $\tf -50.0pt$ instead of the
normal $\tf -1000pt$. The helper is defined as:
-\typebuffer[option=TEX][definitions-1]
+\typebuffer[definition-1][option=TEX]
or
-\typebuffer[option=TEX][definitions-2]
+\typebuffer[definition-2][option=TEX]
-The result of the following example is shown in \in {figures} [fig:prevdepth-1]
-\in {and} [fig:prevdepth-2]. The first case is what we normally have in text and
-we haven't set \type {prevdepth} explicitly between lines so \TEX\ will just look
-at the depth of the lines. In the second case the depth is ignored when less than
-the criterium which is why, when we set the depth of the box to a negative value
-we get somewhat interesting skips.
+The result is shown in \in {figures} [fig:prevdepth-1] \in {and}
+[fig:prevdepth-2]. The first case is what we normally have in text and we haven't
+set \type {prevdepth} explicitly between lines so \TEX\ will just look at the
+depth of the lines. In the second case the depth is ignored when less than the
+criterium which is why, when we set the depth of the box to a negative value we
+get somewhat interesting skips.
\startplacefigure[reference=fig:prevdepth-1]
\showmakeup[line]
@@ -1355,6 +1357,8 @@ we get with positive values:
\egroup
\stopbuffer
+\typebuffer[example][option=TEX]
+
\startplacefigure[reference=fig:prevdepth-3]
\showmakeup[line]
\ignoredepthcriterium50pt
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-registers.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-registers.tex
index 233a8c1788d..cdd026fb6fb 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-registers.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-registers.tex
@@ -282,5 +282,211 @@ macros.
\stopsectionlevel
-\stopdocument
+\startsectionlevel[title=Units]
+
+The \LUAMETATEX\ engine supports the following units. The first batch is constant
+with hard coded fine tuned values. The second set is related to the current font.
+The last group is kind of special, the \type {es} is a replacement for the \type
+{in} and has a little sister in \type {ts}. The \type {dk} is dedicated to the
+master and makes a nice offset for so called \TEX\ pages that we use for demos.
+
+\starttabulate[|Tl|Tr|l|]
+\FL
+\NC pt \NC \thewithoutunit\dimexpr1pt \NC point \NC \NR
+\NC bp \NC \thewithoutunit\dimexpr1bp \NC big point (aka postscript point) \NC \NR
+\NC in \NC \thewithoutunit\dimexpr1in \NC inch \NC \NR
+\NC cm \NC \thewithoutunit\dimexpr1cm \NC centimeter \NC \NR
+\NC mm \NC \thewithoutunit\dimexpr1mm \NC milimeter \NC \NR
+\NC dd \NC \thewithoutunit\dimexpr1dd \NC didot \NC \NR
+\NC cc \NC \thewithoutunit\dimexpr1cc \NC cicero \NC \NR
+\NC pc \NC \thewithoutunit\dimexpr1pc \NC pica \NC \NR
+\NC sp \NC \thewithoutunit\dimexpr1sp \NC scaled points \NC \NR
+\NC px \NC \thewithoutunit\dimexpr1sp \NC pixel \NC \NR
+\ML
+\NC ex \NC \thewithoutunit\dimexpr1ex \NC ex height \NC \NR
+\NC em \NC \thewithoutunit\dimexpr1em \NC em width \NC \NR
+\NC mu \NC $\tt\thewithoutunit\onemuskip$ \NC math unit \NC \NR
+\ML
+\NC ts \NC \thewithoutunit\dimexpr1ts \NC tove \NC \NR
+\NC es \NC \thewithoutunit\dimexpr1es \NC edith \NC \NR
+\NC eu \NC \thewithoutunit\dimexpr1eu \NC european unit \NC \NR
+\NC dk \NC \thewithoutunit\dimexpr1dk \NC knuth \NC \NR
+\LL
+\stoptabulate
+
+The \type {fi[lll]} unit is not really a unit but a multiplier for infinite
+stretch and shrink; original \TEX\ doesn't have the simple \type {fi}.
+
+In addition to these we can have many more. In principle a user can define
+additional ones but there's always a danger of clashing. For users we reserve the
+units starting with an \type{u}. Here is how you define your own, we show three
+variants:
+
+\startbuffer
+\newdimension \FooA \FooA 1.23pt
+\newdimen \FooB \FooB 12.3pt
+\protected\def\FooC {\the\dimexpr\FooA +\FooB\relax}
+
+\pushoverloadmode % just in case
+ \newuserunit\FooA ua
+ \newuserunit\FooB ub
+ \newuserunit\FooC uc
+\popoverloadmode
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+And this is how they show up:
+
+\startbuffer
+\the\dimexpr 2 ua \relax\quad
+\the\dimexpr 2 ub \relax\quad
+\the\dimexpr 2 uc \relax
+\stopbuffer
+
+\getbuffer
+
+with
+
+\typebuffer[option=TEX]
+
+The following additional units are predefined (reserved). The values are in
+points and some depend on the current layout and document font.
+
+\starttabulate[|T|Tr|l|]
+\NC pi \NC \thewithoutunit\dimexpr 1pi \NC {\tt\pi} for Mikael \NC \NR
+\NC ft \NC \thewithoutunit\dimexpr 1ft \NC \type {foot} for Alan \NC \NR
+\NC fs \NC \thewithoutunit\dimexpr 1fs \NC (global body) font size \NC \NR
+\NC tw \NC \thewithoutunit\dimexpr 1tw \NC (layout) text width \NC \NR
+\NC th \NC \thewithoutunit\dimexpr 1th \NC (layout) text height \NC \NR
+\NC hs \NC \thewithoutunit\dimexpr 1hs \NC (current) hsize \NC \NR
+\NC vs \NC \thewithoutunit\dimexpr 1vs \NC (current) vsize \NC \NR
+\NC cd \NC \thewithoutunit\dimexpr 1cd \NC (when set) column distance \NC \NR % todo
+\NC cw \NC \thewithoutunit\dimexpr 1cw \NC (when set) column width \NC \NR % todo
+\NC cx \NC \thewithoutunit\dimexpr 1cx \NC combination cell width \NC \NR
+\NC uu \NC \thewithoutunit\dimexpr 1uu \NC user unit (\METAFUN) \NC \NR
+\NC fw \NC \thewithoutunit\dimexpr 1fw \NC framed width \NC \NR
+\NC fh \NC \thewithoutunit\dimexpr 1fh \NC framed height \NC \NR
+\NC fo \NC \thewithoutunit\dimexpr 1fo \NC framed offset \NC \NR
+\NC lw \NC \thewithoutunit\dimexpr 1lw \NC line width \NC \NR
+\NC sh \NC \thewithoutunit\dimexpr 1sh \NC strut height \NC \NR
+\NC sd \NC \thewithoutunit\dimexpr 1sd \NC strut depth \NC \NR
+\NC st \NC \thewithoutunit\dimexpr 1st \NC strut total \NC \NR
+\NC ch \NC \thewithoutunit\dimexpr 1ch \NC width of zero (css) \NC \NR
+\NC fa \NC \thewithoutunit\dimexpr 1fa \NC font ascender \NC \NR
+\NC fd \NC \thewithoutunit\dimexpr 1fd \NC font descender \NC \NR
+\NC fc \NC \thewithoutunit\dimexpr 1fc \NC font cap height \NC \NR
+\stoptabulate
+
+Here is an example of usage:
+
+\startbuffer
+\startcombination[nx=4,ny=1]
+ {\ruledhbox to 1cx{\strut one}} {1}
+ {\ruledhbox to 1cx{\strut two}} {2}
+ {\ruledhbox to 1cx{\strut three}} {3}
+ {\ruledhbox to 1cx{\strut four}} {4}
+\stopcombination
+\stopbuffer
+
+\usemodule[system-units]
+\startplacefigure[title=A map of available units,reference=fig:unitsmap]
+ \framed[offset=1ex]{\showunitsmap}
+\stopplacefigure
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+The \type {uu} can be set by users using the \type {\uunit} dimension variable.
+The default valu sis 1cm. Its current value is also known at the \METAPOST\ end,
+as demonstrated in \in {figure} [fig:userunits].
+
+\startbuffer
+\startcombination[nx=2,ny=1]
+ \startcontent
+ \uunit=1cm
+ \framed[offset=1uu]
+ \bgroup
+ \startMPcode
+ fill fullcircle scaled 3uu withcolor "darkred" ;
+ fill fullcircle scaled 2cm withcolor "darkgreen" ;
+ \stopMPcode
+ \egroup
+ \stopcontent
+ \startcaption
+ \type {\uunit = 1cm}
+ \stopcaption
+ \startcontent
+ \uunit=1cx
+ \framed[offset=.1uu]
+ \bgroup
+ \startMPcode
+ fill fullcircle scaled .5uu withcolor "darkblue" ;
+ fill fullcircle scaled 2cm withcolor "darkyellow" ;
+ \stopMPcode
+ \egroup
+ \stopcontent
+ \startcaption
+ \type {\uunit = 1cx}
+ \stopcaption
+\stopcombination
+\stopbuffer
+
+% \framed[offset=1uu]
+% \bgroup
+% \startMPcode
+% save uu ; numeric uu ; uu := 1cm ;
+% fill fullcircle scaled 3uu withcolor "darkcyan" ;
+% fill fullcircle scaled 2cm withcolor "darkmagenta" ;
+% \stopMPcode
+% \egroup
+
+\typebuffer[option=TEX]
+
+There is one catch here. If you use your own \type {uu} as numeric, you might
+need this:
+
+\starttyping[option=MP]
+save uu ; numeric uu ; uu := 1cm ;
+\stoptyping
+
+That is: make sure the meaning is restored afterwards and explicitly declare the
+variable. But this is good practice anyway when you generate multiple graphics
+using the same \METAPOST\ instance.
+
+\startplacefigure[reference=fig:userunits,title={Shared user units in \TEX\ and \METAFUN.}]
+ \getbuffer
+\stopplacefigure
+
+There a few units not mentioned yet and those concern math, where we need to adapt to
+the current style.
+
+\protected\def\ShowMathUnits#1%
+ {\im{#1x\mathord{+
+ {\darkgray \vrule width 1pt depth 0pt height 1ex \relax}%
+ {\darkred \vrule width 1pt depth 0pt height 1ma \relax}%
+ {\darkgreen\vrule width 1pt depth 0pt height 1mx \relax}%
+ {\darkblue \vrule width 1pt depth 0pt height 1mq \relax}%
+ x}}}
+
+\startlinecorrection
+\startcombination[nx=3,ny=1]
+ {\scale[scale=6000]{\ShowMathUnits\textstyle}} {text style}
+ {\scale[scale=6000]{\ShowMathUnits\scriptstyle}} {script style}
+ {\scale[scale=6000]{\ShowMathUnits\scriptscriptstyle}} {script script style}
+\stopcombination
+\stoplinecorrection
+
+The bars show \type {1ex}, \type {1ma} (axis), \type {1mx} (ex|-|height) and
+\type {1mq} (em|-|width or quad). The last three adapt themselves to the style.
+Often the \type {mx} makes more sense than \type {ex}.
+
+\stopsectionlevel
+
+\page
+
+\stopdocument
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-style.tex b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-style.tex
index 9d3bcdbb337..c0111a97d4a 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-style.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-style.tex
@@ -14,6 +14,7 @@
[document]
[title=No Title,
author=No Author,
+ coauthor=,
color=NoColor]
\setupbodyfont
@@ -124,7 +125,9 @@
\startsectionlevel[title=Colofon,number=no,saveinlist=no]
\starttabulate
- \NC Author \NC Hans Hagen \NC \NR
+ \NC Author \NC Hans Hagen
+ \doifdocumentvariable{coauthor}{ & \documentvariable{coauthor}}
+ \NC \NR
\NC \CONTEXT \NC \contextversion \NC \NR
\NC \LUAMETATEX \NC \texengineversion \NC \NR
\NC Support \NC www.pragma-ade.com \NC \NR
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-building.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-building.tex
index 277d39251db..e4c00d3a241 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-building.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-building.tex
@@ -393,7 +393,7 @@ There is however a catch. The keyword scanners in \LUAMETATEX\ are implemented
slightly different. When \TEX\ scans a keyword it will (case insensitive) scan
for a whole keyword. So, it scans for \type {height} and when it doesn't find it
it will scan for \type {depth} etc. When it does find a keyword in this case it
-expects a dimension next. When that criterium is not met it will issue an error
+expects a dimension next. When that criterion is not met it will issue an error
message.
In order to avoid look ahead failures like that it is recommended to end the
@@ -457,10 +457,10 @@ up such that it can adapt itself:
\hbox to 3cm {x\leaders\hrule\hfil x}
\hbox{x \vrule width 4cm \relax x}
\hbox{x \srule width 4cm \relax x}
-\hbox{x \vrule font \font char `( width 4cm \relax x}
\hbox{x \srule font \font char `( width 4cm \relax x}
\hbox{$x \srule fam \fam char `( width 4cm \relax x$}
-\hbox{$x \vrule fam \fam char `( width 4cm \relax x$}
+% \hbox{x \vrule font \font char `( width 4cm \relax x}
+% \hbox{$x \vrule fam \fam char `( width 4cm \relax x$}
\stopbuffer
\typebuffer
@@ -885,7 +885,7 @@ criteria makes a difference. Experiments with this demonstrated the usual: when
asked what looks best contradictions mix with expectations and being triggered by
events that one related to \TEX, like successive hyphenated lines.
-The \prm {linebreakcriterium} parameter can be set to a value made from four bytes. We're
+The \prm {linebreakcriterion} parameter can be set to a value made from four bytes. We're
not going to explain the magic numbers because they come from and are discussed in original
\TEX. It is enough to know that we have four criteria:
@@ -908,9 +908,9 @@ The original decisions are made in the following way:
\starttyping
function loose(badness)
- if badness > loose_criterium then
+ if badness > loose_criterion then
return very_loose_fit
- elseif badness > decent_criterium then
+ elseif badness > decent_criterion then
return loose_fit
else {
return decent_fit
@@ -918,7 +918,7 @@ function loose(badness)
end
function tight(badness)
- if badness > decent_criterium then
+ if badness > decent_criterion then
return tight_fit
else {
return decent_fit
@@ -957,7 +957,7 @@ doesn't work out as you expect. Don Knuth did a good job on the heuristics and
after many decades there is no real need to change something. Consider it a
playground.
-The parameter \prm {ignoredepthcriterium} is set to -1000pt at startup and is a
+The parameter \prm {ignoredepthcriterion} is set to -1000pt at startup and is a
special signal for \prm {prevdepth}. You can change the value locally for
educational purposes but best not mess with this standard value in production
code unless you want special effects.
@@ -1181,7 +1181,7 @@ variable is global.
Traditional \TEX\ has the \prm {parfillskip} parameter that determines the way
the last line is filled. In \LUAMETATEX\ we also have \prm {parfillleftskip}. The
counterparts for the first line are \prm {parinitleftskip} and \prm
-{parinitrightskip}.
+{parinitrightskip}. We also have \prm {parfillrightskip} as consistency alias.
\startbuffer
\leftskip 2em
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 803b0427b04..89265a6665a 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
@@ -223,7 +223,7 @@ state is with respect to the \quote {current page}. The possible values for the
\stopsubsection
-\startsubsection[title={\cbk {build_page_insert}}]
+\startsubsection[title={\cbk {insert_distance}}]
\topicindex{callbacks+inserts}
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 46d986bfb57..a72a9236f69 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
@@ -270,11 +270,11 @@ live in a \UNICODE\ galaxy that is no real problem.
\stopsubsection
-\startsubsection[title={\prm {Uchar}}]
+\startsubsection[title={\prm {tocharacter}}]
\topicindex{\UNICODE}
-The expandable command \prm {Uchar} reads a number between~0 and $1{,}114{,}111$
+The expandable command \prm {tocharacter} reads a number between~0 and $1{,}114{,}111$
and expands to the associated \UNICODE\ character.
\stopsubsection
@@ -1258,15 +1258,15 @@ In addition to these \ASCII\ combinations, we also support some \UNICODE\
variants. The extra comparison options are:
\starttabulate[|l|c|c|l|]
-\DB character \BC \BC \BC operation \NC \NR
+\DB character \BC \BC \BC operation \NC \NR
\TB
-\NC \type {0x2208} \NC $\Uchar"2208$ \NC \NC element of \NC \NR
-\NC \type {0x2209} \NC $\Uchar"2209$ \NC \NC not element of \NC \NR
-\NC \type {0x2260} \NC $\Uchar"2260$ \NC \type {!=} \NC not equal \NC \NR
-\NC \type {0x2264} \NC $\Uchar"2264$ \NC \type {!>} \NC less equal \NC \NR
-\NC \type {0x2265} \NC $\Uchar"2265$ \NC \type {!<} \NC greater equal \NC \NR
-\NC \type {0x2270} \NC $\Uchar"2270$ \NC \NC not less equal \NC \NR
-\NC \type {0x2271} \NC $\Uchar"2271$ \NC \NC not greater equal \NC \NR
+\NC \type {0x2208} \NC $\tocharacter"2208$ \NC \NC element of \NC \NR
+\NC \type {0x2209} \NC $\tocharacter"2209$ \NC \NC not element of \NC \NR
+\NC \type {0x2260} \NC $\tocharacter"2260$ \NC \type {!=} \NC not equal \NC \NR
+\NC \type {0x2264} \NC $\tocharacter"2264$ \NC \type {!>} \NC less equal \NC \NR
+\NC \type {0x2265} \NC $\tocharacter"2265$ \NC \type {!<} \NC greater equal \NC \NR
+\NC \type {0x2270} \NC $\tocharacter"2270$ \NC \NC not less equal \NC \NR
+\NC \type {0x2271} \NC $\tocharacter"2271$ \NC \NC not greater equal \NC \NR
\LL
\stoptabulate
@@ -1767,6 +1767,30 @@ else \quote {last} has been seen.
\stopsection
+\startsection[title=Kerns and penalties]
+
+\startsubsection[title=\prm {hkern} and \prm {vkern}]
+
+\topicindex {kerns}
+
+These two primitives complement \prm {hskip} and \prm {vskip} and force the right
+mode when issued. Contrary to the skips, internally we still have a common kern
+command code but that is not something the user has to worry about.
+
+\stopsubsection
+
+\startsubsection[title=\prm {hpenalty} and \prm {vpenalty}]
+
+\topicindex {penalties}
+
+As the kern and skip related primitives mentioned in the in the previous section
+these two primitives are there fort consistency: they force the right (related)
+mode. (Sometimes being a bit more explicit is cleaner.)
+
+\stopsubsection
+
+\stopsection
+
\startsection[title=Scanning]
\startsubsection[title=Keywords]
@@ -2488,6 +2512,38 @@ Unit equivalent to ten Toves or one Edith.
\stopsection
+\startsection[title=Registers]
+
+
+\startsubsection[title={32 bit floats}]
+
+The engine has native float registers which means that we have a similar set of
+primitives as for dimensions and integers: \prm {float}, \prm {floatdef}, \prm
+{floatexpr} and \prm {iffloat}. In the context if an integer a rounded value is
+used, in the context of a dimensions the floating point number is interpreted as
+points. Internally floats are stored as so called posits, which gives more accuracy
+for smaller values.
+
+\stopsubsection
+
+\startsubsection[title={32 bit posits}]
+
+{\em This is a playground. It will stay but might evolve.}
+
+\stopsubsection
+
+\startsubsection[title={Extra features}]
+
+There are \prm {ifabsnum}, \prm {ifabsdim} and \prm {ifabsfloat} that compare
+absolute values of quantities. The primitives \prm{ifzeronum}, \prm{ifzerodim},
+\prm{ifzerofloat} do a fast test for zero. The \prm {ifintervalnum}, \prm
+{ifintervaldim} and \prm {ifintervalfloat} primitives take a delta and two values
+and check if these values overlap within the ranges dedicated by the delta.
+
+\stopsubsection
+
+\stopsection
+
\startsection[title=Expressions]
\startsubsection[title={Rounding and scaling}]
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 7f0a7a62c3b..2b3fc2d1c24 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
@@ -1011,26 +1011,26 @@ values only makes sense in the perspective of the used macro package.
\stopsubsection
-\startsubsection[title={Tracing}]
-
-The \prm {tracingfonts} primitive that has been inherited from \PDFTEX\ has
-been adapted to support variants in reporting the font. The reason for this
-extension is that a csname not always makes sense. The zero case is the default.
-
-\starttabulate[|l|l|]
-\DB value \BC reported \NC \NR
-\TB
-\NC \type{0} \NC \type{\foo xyz} \NC \NR
-\NC \type{1} \NC \type{\foo (bar)} \NC \NR
-\NC \type{2} \NC \type{<bar> xyz} \NC \NR
-\NC \type{3} \NC \type{<bar @ ..pt> xyz} \NC \NR
-\NC \type{4} \NC \type{<id>} \NC \NR
-\NC \type{5} \NC \type{<id: bar>} \NC \NR
-\NC \type{6} \NC \type{<id: bar @ ..pt> xyz} \NC \NR
-\LL
-\stoptabulate
-
-\stopsubsection
+% \startsubsection[title={Tracing}]
+%
+% The \prm {tracingfonts} primitive that has been inherited from \PDFTEX\ has
+% been adapted to support variants in reporting the font. The reason for this
+% extension is that a csname not always makes sense. The zero case is the default.
+%
+% \starttabulate[|l|l|]
+% \DB value \BC reported \NC \NR
+% \TB
+% \NC \type{0} \NC \type{\foo xyz} \NC \NR
+% \NC \type{1} \NC \type{\foo (bar)} \NC \NR
+% \NC \type{2} \NC \type{<bar> xyz} \NC \NR
+% \NC \type{3} \NC \type{<bar @ ..pt> xyz} \NC \NR
+% \NC \type{4} \NC \type{<id>} \NC \NR
+% \NC \type{5} \NC \type{<id: bar>} \NC \NR
+% \NC \type{6} \NC \type{<id: bar @ ..pt> xyz} \NC \NR
+% \LL
+% \stoptabulate
+%
+% \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 142f18c3259..c793f39192d 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
@@ -116,6 +116,17 @@ additions to \METAPOST: in due time these will be discussed in the \LUAMETAFUN\
manual (the official \METAPOST\ manual is maintained elsewhere and should not
discuss features that are not in the \LUATEX\ version).
+This manual is not a tutorial. It is also not a replacement for {\em The \TEX\
+Book}. It just collects (as we go) what is available in \LUAMETATEX, and
+therefore it always is a bit behind; actually the \TEX\ sources of the manuals
+might be ahead of the file you read right now. For new functionality you can look
+at documents (or source files or test files) that come with \CONTEXT\ where it is
+put into perspective. Some new primitives might speak for themselves, especially
+when you are familiar with \TEX. Some might not give a clue at all even with a
+bit of explanation: if so, just forget about them. You can always ask on the
+\CONTEXT\ list for the how, when and why of new features. It all comes for free,
+so keep that in mind when you are going to complain.
+
\blank[big]
Hans Hagen
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 61ec42ec36e..5843084f5e8 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
@@ -68,14 +68,13 @@ transformed in the font engine later on, just as hyphenation directive can
be added. Eventually one (normally) gets a mix of glyphs, font kerns from
a sequence of glyphs
-In math mode \type {abc} results in three simple ordinary noads and \type {a
-b c} is equivalent to that: three noads. But \type {a bc} results in two
-ordinary noads where the second one has a sublist of two ordinary noads.
-Because characters have class properties, \type {( a + b = c )} results in a
-simple open noad, a simple ordinary, a simple binary, a simple ordinary, a
-simple relation, a simple ordinary and simple close noad. The next samples show a
-bit of this; in order to see th effects spacing between ordinary atoms set
-to \type {9mu}.
+In math mode \type {abc} results in three simple ordinary noads and \type {a b c}
+is equivalent to that: three noads. But \type {a bc} results in two ordinary
+noads where the second one has a sublist of two ordinary noads. Because
+characters have class properties, \type {( a + b = c )} results in a simple open
+noad, a simple ordinary, a simple binary, a simple ordinary, a simple relation, a
+simple ordinary and simple close noad. The next samples show a bit of this; in
+order to see the effects of spacing between ordinary atoms set it to \type {9mu}.
\startbuffer
\typebuffer[sample]
@@ -635,7 +634,7 @@ are not bound to fonts because we don't know if have a font involved.
\startsection[title={Math styles}]
-\startsubsection[title={\prm {mathstyle}, \prm {mathstackstyle} and \prm {Ustyle}}]
+\startsubsection[title={\prm {mathstyle}, \prm {mathstackstyle} and \prm {givenmathstyle}}]
\topicindex {math+styles}
@@ -756,12 +755,12 @@ that when you got it, and want to act upon it, you need to remap it onto say \pr
why we also have a more efficient alternative that you can use in macros:
\starttyping
-\normalexpand{ ... \Ustyle\the\mathstyle ...}
-\normalexpand{ ... \Ustyle\the\mathstackstyle ...}
+\normalexpand{ ... \givenmathstyle\the\mathstyle ...}
+\normalexpand{ ... \givenmathstyle\the\mathstackstyle ...}
\stoptyping
-This new primitive \prm {Ustyle} accepts a numeric value. The \prm
-{mathstackstyle} primitive is just a bonus (it complements \prm {Ustack}).
+This new primitive \prm {givenmathstyle} accepts a numeric value. The \prm
+{mathstackstyle} primitive is just a bonus (it complements \prm {mathstack}).
The styles that the different math components and their subcomponents start out
with are no longer hard coded but can be set at runtime:
@@ -815,7 +814,7 @@ are no real reasons to change them.
\stopsubsection
-\startsubsection[title={\prm {Ustack}}]
+\startsubsection[title={\prm {mathstack}}]
\topicindex {math+stacks}
@@ -823,13 +822,13 @@ There are a few math commands in \TEX\ where the style that will be used is not
known straight from the start. These commands (\prm {over}, \prm {atop},
\prm {overwithdelims}, \prm {atopwithdelims}) would therefore normally return
wrong values for \prm {mathstyle}. To fix this, \LUATEX\ introduces a special
-prefix command: \prm {Ustack}:
+prefix command: \prm {mathstack}:
\starttyping
-$\Ustack {a \over b}$
+$\mathstack {a \over b}$
\stoptyping
-The \prm {Ustack} command will scan the next brace and start a new math group
+The \prm {mathstack} command will scan the next brace and start a new math group
with the correct (numerator) math style. The \prm {mathstackstyle} primitive
relates to this feature.
@@ -1526,16 +1525,16 @@ front.
\startbuffer
$
- x \Usubscript {-}
- \frozen\Umathsubshiftdown\textstyle 0pt x \Usubscript {0}
- {\frozen\Umathsubshiftdown\textstyle 5pt x \Usubscript {5}}
- x \Usubscript {0}
- {\frozen\Umathsubshiftdown\textstyle 15pt x \Usubscript {15}}
- x \Usubscript {0}
- {\frozen\Umathsubshiftdown\textstyle 20pt x \Usubscript {20}}
- x \Usubscript {0}
- \frozen\Umathsubshiftdown\textstyle 10pt x \Usubscript {10}
- x \Usubscript {0}
+ x \subscript {-}
+ \frozen\Umathsubshiftdown\textstyle 0pt x \subscript {0}
+ {\frozen\Umathsubshiftdown\textstyle 5pt x \subscript {5}}
+ x \subscript {0}
+ {\frozen\Umathsubshiftdown\textstyle 15pt x \subscript {15}}
+ x \subscript {0}
+ {\frozen\Umathsubshiftdown\textstyle 20pt x \subscript {20}}
+ x \subscript {0}
+ \frozen\Umathsubshiftdown\textstyle 10pt x \subscript {10}
+ x \subscript {0}
$
\stopbuffer
@@ -1555,17 +1554,17 @@ unprocessed math list. The result looks as follows:
\startsubsection[title={Arbitrary atoms with \prm {mathatom} etc.}]
-The original \TEX\ engine has primitives like \prm {mathord} and a limited set of
-possible atoms. In \LUAMETATEX\ we have many more built in and you can add more.
-It will take a while before we have documented all the new math features and more
-details can be found in the manuals that come with \CONTEXT\ for which all this
-was implemented. In addition to \prm {mathordinary} (aka \prm {mathord}), \prm
-{mathoperator} (aka \prm {mathop}), \prm {mathbinary} (aka \prm {mathbin}), \prm
-{mathrelation} (aka \prm {mathrel}), \prm {mathopen}, \prm {mathclose}, \prm
-{mathpunctuation} (aka {mathpunct}) and \prm {mathinner} we have \prm
-{mathfraction}, \prm {mathradical}, \prm {mathmiddle}, \prm {mathaccent}, \prm
-{mathfenced}, \prm {mathghost} and the existing \prm {mathunderline} (aka \prm
-{underline}) and \prm {mathoverline} (aka \prm {overline}) class driven atoms.
+% The original \TEX\ engine has primitives like \prm {mathord} and a limited set of
+% possible atoms. In \LUAMETATEX\ we have many more built in and you can add more.
+% It will take a while before we have documented all the new math features and more
+% details can be found in the manuals that come with \CONTEXT\ for which all this
+% was implemented. In addition to \prm {mathordinary} (aka \prm {mathord}), \prm
+% {mathoperator} (aka \prm {mathop}), \prm {mathbinary} (aka \prm {mathbin}), \prm
+% {mathrelation} (aka \prm {mathrel}), \prm {mathopen}, \prm {mathclose}, \prm
+% {mathpunctuation} (aka {mathpunct}) and \prm {mathinner} we have \prm
+% {mathfraction}, \prm {mathradical}, \prm {mathmiddle}, \prm {mathaccent}, \prm
+% {mathfenced}, \prm {mathghost} and the existing \prm {mathunderline} (aka \prm
+% {underline}) and \prm {mathoverline} (aka \prm {overline}) class driven atoms.
The \prm {mathatom} primitive is the generic one and it accepts a couple of
keywords:
@@ -2115,12 +2114,12 @@ These render as: \getbuffer
\stopsubsection
-\startsubsection[title={Math styles: \prm {Ustyle}}]
+\startsubsection[title={Math styles: \prm {givenmathstyle}}]
This primitive accepts a style identifier:
\starttyping
-\Ustyle \displaystyle
+\givenmathstyle \displaystyle
\stoptyping
This in itself is not spectacular because it is equivalent to
@@ -2135,9 +2134,12 @@ zero upto seven (like the ones reported by the primitive \prm {mathstyle}). So,
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$
+$\givenmathstyle0 \number\mathstyle
+ \givenmathstyle7 \number\mathstyle$
+$\givenmathstyle\displaystyle \number\mathstyle
+ \givenmathstyle\crampedscriptscriptstyle \number\mathstyle$
+$\displaystyle \number\mathstyle
+ \crampedscriptscriptstyle \number\mathstyle$
\stopbuffer
Like: \inlinebuffer . Values outside the valid range are ignored.
@@ -2194,8 +2196,8 @@ influence the spacing. The numbers are the same as for character classes.
\startsection[title={Extracting values}]
-\startsubsection[title={Codes and using \prm {Umathcode}, \prm {Umathcharclass}, \prm
-{Umathcharfam} and \prm {Umathcharslot}}]
+\startsubsection[title={Codes and using \prm {Umathcode}, \prm {mathcharclass}, \prm
+{mathcharfam} and \prm {mathcharslot}}]
\topicindex {math+codes}
@@ -2210,7 +2212,7 @@ you can extract the components of a math character. Say that we have defined:
then
\starttyping
-[\Umathcharclass\Umathcode1] [\Umathcharfam\Umathcode1] [\Umathcharslot\Umathcode1]
+[\mathcharclass\Umathcode1] [\Umathcharfam\Umathcode1] [\Umathcharslot\Umathcode1]
\stoptyping
which will return:
@@ -2227,7 +2229,7 @@ These commands are provided as convenience. Before they became available you
could do the following:
\starttyping
-\def\Umathcharclass{\numexpr
+\def\mathcharclass{\numexpr
\directlua{tex.print(tex.getmathcode(token.scan_int())[1])}
\relax}
\def\Umathcharfam{\numexpr
@@ -2279,8 +2281,8 @@ identifier that determines in what style we end up in.
\stopsubsection
-\startsubsection[title={Verbose versions of single|-|character math commands like \prm {Usuperscript}
-and \prm {Usubscript}}]
+\startsubsection[title={Verbose versions of single|-|character math commands like \prm {superscript}
+and \prm {subscript}}]
\topicindex {math+styles}
@@ -2290,8 +2292,8 @@ and \prm {Usubscript}}]
\starttabulate[|l|l|]
\DB primitive \BC explanation \NC \NR
\TB
-\NC \prm {Usuperscript} \NC duplicates the functionality of \type {^} \NC \NR
-\NC \prm {Usubscript} \NC duplicates the functionality of \type {_} \NC \NR
+\NC \prm {superscript} \NC duplicates the functionality of \type {^} \NC \NR
+\NC \prm {subscript} \NC duplicates the functionality of \type {_} \NC \NR
\NC \prm {Ustartmath} \NC duplicates the functionality of \type {$}, % $
when used in non-math mode. \NC \NR
\NC \prm {Ustopmath} \NC duplicates the functionality of \type {$}, % $
@@ -2309,7 +2311,7 @@ the four mathon|/|mathoff commands with explicit dollar sign(s).
\stopsubsection
-\startsubsection[title={Script commands \prm {Unosuperscript}, \prm {Unosubscript}, \prm {Unosuperprescript} and \prm {Unosubprescript}}]
+\startsubsection[title={Script commands \prm {nosuperscript}, \prm {nosubscript}, \prm {nosuperprescript} and \prm {nosubprescript}}]
\topicindex {math+styles}
\topicindex {math+scripts}
@@ -2319,10 +2321,10 @@ time of rendering). So,
\startbuffer[script]
$
- x\Usuperscript {1}\Usubscript {2} =
- x\Unosuperscript{1}\Unosubscript{2} =
- x\Usuperscript {1}\Unosubscript{2} =
- x\Unosuperscript{1}\Usubscript {2}
+ x\superscript {1}\subscript {2} =
+ x\nosuperscript{1}\nosubscript{2} =
+ x\superscript {1}\nosubscript{2} =
+ x\nosuperscript{1}\subscript {2}
$
\stopbuffer
@@ -2332,7 +2334,7 @@ results in \inlinebuffer[script].
\stopsubsection
-\startsubsection[title={Script commands \prm {Ushiftedsuperscript}, \prm {Ushiftedsubscript}, \prm {Ushiftedsuperprescript} and \prm {Ushiftedsubprescript}}]
+\startsubsection[title={Script commands \prm {shiftedsuperscript}, \prm {shiftedsubscript}, \prm {shiftedsuperprescript} and \prm {shiftedsubprescript}}]
\topicindex {math+styles}
\topicindex {math+scripts}
@@ -2344,10 +2346,10 @@ are shown:
\startbuffer[script]
$
- x\Usuperscript {1}\Usubscript {2} =
- x\Ushiftedsuperscript{1}\Ushiftedsubscript{2} =
- x\Usuperscript {1}\Ushiftedsubscript{2} =
- x\Ushiftedsuperscript{1}\Usubscript {2}
+ x\superscript {1}\subscript {2} =
+ x\shiftedsuperscript{1}\shiftedsubscript{2} =
+ x\superscript {1}\shiftedsubscript{2} =
+ x\shiftedsuperscript{1}\subscript {2}
$
\stopbuffer
@@ -2357,7 +2359,7 @@ results in \inlinebuffer[script].
\stopsubsection
-\startsubsection[title={Injecting primes with \prm {Uprimescript}}]
+\startsubsection[title={Injecting primes with \prm {primescript}}]
This one is a bit special. In \LUAMETATEX\ a prime is a native element of a
nucleus, alongside the two prescript and two postscripts. The most confusing
@@ -2367,9 +2369,9 @@ are applied so we don't covert it. That leaves three cases:
\startbuffer[script]
$
- a \Uprimescript{1} \Usuperscript{2} \Usubscript {3} +
- b \Usubscript {3} \Uprimescript{1} +
- c \Uprimescript{1} \Usubscript {3} = d
+ a \primescript{1} \superscript{2} \subscript {3} +
+ b \subscript {3} \primescript{1} +
+ c \primescript{1} \subscript {3} = d
$
\stopbuffer
@@ -2380,16 +2382,16 @@ it were an index.
\stopsubsection
-\startsubsection[title={Prescripts with \prm {Usuperprescript} and \prm {Usubprescript}}]
+\startsubsection[title={Prescripts with \prm {superprescript} and \prm {subprescript}}]
\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
+ {\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
@@ -2409,15 +2411,15 @@ 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}
+{\tf X}\superscript{1} \quad
+{\tf X} \subscript{2} \quad
+{\tf X}\superscript{1}\subscript{2} \quad
+{\tf X}\superscript{1} \superprescript{3} \quad
+{\tf X} \subscript{2} \subprescript{4}\quad
+{\tf X}\superscript{1}\subscript{2}\superprescript{3}\subprescript{4}\quad
+{\tf X} \superprescript{3} \quad
+{\tf X} \subprescript{4}\quad
+{\tf X} \superprescript{3}\subprescript{4}
$}
\stopbuffer
@@ -2521,16 +2523,16 @@ If you also want to see something on the console make sure to set \prm
\startsection[title={Classes}]
-\startsubsection[title={Forcing classes with \prm {Umathclass}}]
+\startsubsection[title={Forcing classes with \prm {mathclass}}]
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$
+$x\mathopen {!}+123+\mathclose {!}x$
+$x\mathclass4 `! +123+\mathclass5 `! x$
+$x ! +123+ ! x$
+$x\mathclose {!}+123+\mathopen {!}x$
+$x\mathclass5 `! +123+\mathclass4 `! x$
\stopbuffer
\typebuffer
@@ -2655,17 +2657,21 @@ they indicate pre- and postscripts.
\starttabulate[|c|c|c|c|]
\NC \type {^} \NC \NC super \NC post \NC \NR
\NC \type {_} \NC \NC sub \NC post \NC \NR
-\NC \type {^^} \NC \NC super \NC pre \NC \NR
-\NC \type {__} \NC \NC sub \NC pre \NC \NR
-\NC \type {^^^} \NC shifted \NC super \NC post \NC \NR
-\NC \type {___} \NC shifted \NC sub \NC post \NC \NR
+\NC \type {^^} \NC \NC super \NC post \NC \NR
+\NC \type {__} \NC \NC sub \NC post \NC \NR
+\NC \type {^^^} \NC shifted \NC super \NC pre \NC \NR
+\NC \type {___} \NC shifted \NC sub \NC pre \NC \NR
\NC \type {^^^^} \NC shifted \NC super \NC pre \NC \NR
\NC \type {____} \NC shifted \NC sub \NC pre \NC \NR
\stoptabulate
-The shifted variants force a script to be an index and thereby make the other
-script move. This multiple character features used to be optional but is now always
-active.
+The shifted variants force a script to be marked as index. In versions upto 2.10
+a subscript was moved to after the superscript but when we introduced continued
+scripts that feature was disabled (we might bring it back as configurable
+option). The shifted variants now behave the same but at the \LUA\ end one can
+check if they carry this flag. Since 2.11 the one and two character are for post
+while three and four handle prescripts (indices are more common than prescripts).
+The \prm {noscript} command signals that we're up for a new continuation.
Related to this is the issue of double scripts. The regular \TEX\ is to issue
an error message, inject an ordinary node and carry on when asked to. Here we have
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 f19cee29ef6..44fcd6e9edd 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
@@ -906,6 +906,29 @@ 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.
+\startbuffer[luatex]
+
+The following primitives are available in \LUATEX\ but not in \LUAMETATEX. Some
+of these are emulated in \CONTEXT. Some of these primitives that deal with math
+and start with an \type {U} have been renamed to names not having this prefix.
+
+\stopbuffer
+
+\startbuffer[luametatex]
+
+The following primitives are available in \LUAMETATEX\ only. In the meantime the
+\LUAMETATEX\ code base is so different from \LUATEX\ that porting back is no
+longer reasonable. The primitives can roughly be divided in those that relate to
+programming and those that deal with typesetting. In this manual we don't go into
+details about most of these. More information (and examples) of the first
+category can be found in the \quote {primitives} manual that ships with \CONTEXT,
+and the second category is spread over (for instance) the \quote {lowlevel}
+manuals. After all, it is easier to present usage in a known environment. Because
+development of \LUATEX\ and \LUAMETATEX\ is related to \CONTEXT\ development, you
+can also expect to find more examples of usage there.
+
+\stopbuffer
+
\startluacode
local luametatex = tex.primitives()
@@ -921,7 +944,6 @@ if not luatex then
luatex = table.load("luatex-primitives.lua")
end
-
if luatex and luametatex then
local match = string.match
@@ -945,10 +967,7 @@ if luatex and luametatex then
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.getbuffer { "luatex"}
context.blank()
context.startcolumns { n = 2 }
for k, v in table.sortedhash(luatex) do
@@ -964,11 +983,7 @@ if luatex and luametatex then
context.blank()
-- context.page()
-
- context("The following primitives are available in \\LUAMETATEX\\ only. In the meantime ")
- context("the \\LUAMETATEX\\ code base is so different from \\LUATEX\\ that backporting ")
- context("is no longer reasonable.")
-
+ context.getbuffer { "luametatex"}
context.blank()
context.startcolumns { n = 2 }
for k, v in table.sortedhash(luametatex) do
@@ -988,6 +1003,9 @@ end
\stopluacode
+When in the preceding list a primitive has \type {[todo]} in front it is sort of
+experimental and it will be discussed later on when it's stable.
+
\stopsubsection
\startsubsection[title=Changed function names]
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 df4da576e65..a6a17f3531d 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
@@ -69,7 +69,7 @@ numbers (exclusive numbers or bits):
\ShowTeXValues{normalizepar}
\ShowTeXValues{packtype}
\ShowTeXValues{pagecontext}
-\ShowTeXValues{parbegin}
+\ShowTeXValues{partrigger}
\ShowTeXValues{parcontext}
\ShowTeXValues{parmode}
% \ShowTeXValues{runstate}
@@ -1774,19 +1774,22 @@ If the attribute was actually deleted, returns its old value. Otherwise, returns
\startsubsection[title={Glyph handling}][library=node]
-\startsubsubsection[title={\type {firstglyph}}]
+\startsubsubsection[title={\type {firstglyphnode}, \type {firstchar}, \type {firstglyph}}]
+\libindex {firstglyphnode}
+\libindex {firstchar}
\libindex {firstglyph}
\startfunctioncall
-<node> n = node.firstglyph(<node> n)
-<node> n = node.firstglyph(<node> n, <node> m)
+<node> n = node.firstglyphnode(<node> n)
+<node> n = node.firstglyphnode(<node> n, <node> m)
\stopfunctioncall
Returns the first node in the list starting at \type {n} that is a glyph node
with a subtype indicating it is a glyph, or \type {nil}. If \type {m} is given,
processing stops at (but including) that node, otherwise processing stops at the
-end of the list.
+end of the list. The \type {char} and \type {glyph} variants check for the
+protected field being (yet) unset or (already) set.
\stopsubsubsection
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 b3591344ab2..803a0ee2661 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
@@ -39,7 +39,7 @@
[each]
[packed]
-\definesymbol[1][\Uchar"2023]
+\definesymbol[1][\tocharacter"2023]
\definesymbol[2][\endash]
\definesymbol[3][\wait] % we want to catch it
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
index e7505397219..a02e27a3672 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex.tex
@@ -1,5 +1,16 @@
% language=us runpath=texruns:manuals/luametatex
+% \definefontfeature
+% [default]
+% [default]
+% [expansion=quality]
+
+% % \setupalignpass[none]
+% \setupalignpass[decent]
+% % \setupalignpass[quality]
+
+% \pushoverloadmode \let\cdef\edef \let\cdefcsname\edefcsname \popoverloadmode
+
% \enabledirectives[backend.pdf.inmemory]
% \setupalign[profile]
@@ -108,17 +119,35 @@
% End Feburari 2023 I observed 8.2 seconds for 360 pages and making a format needed
% 1.9 seconds instead if the usual 2.1 but that can be a side effect of the terminal
% because the amount of output which is sensitive for refresh delays set. The new
-% target is nwo 50 pages per second for this manual but on this laptop that is
+% target is now 50 pages per second for this manual but on this laptop that is
% unlikely to happen any time soon. With tabulateusesize and tabulatesparseskips
-% experiments enabled we needed 8.1 second and 44.3 pps.
+% experiments enabled we needed 8.1 second and 44.3 pps.% 368 pages may/june 2023:
+%
+% no constant definitions : 8.55
+% constant \*!whatever : 8.47
+% also constant \current* : 8.36
% \enableexperiments [tabulateusesize]
% \enableexperiments [tabulatesparseskips]
-\ifdefined\linebuffering \linebuffering \fi
+% 2023-07-10: context --make > temp.log (after a few times so with cached files)
+%
+% 1.90 sec including mtxrun
+% 1.65 sec tex only
+% 1.45 sec without saving format
+
+% 20230714 : 368 pages
+%
+% mingw : 8.4 (we gained more that for the amd ... more cache and faster mem)
+% rpi 64 : (hdd, not overclocked)
+% amd 10 fitlet : 30.9 12pps (we gained over 25% compared to the 268 page manual)
+
+% \ifdefined\linebuffering \linebuffering \fi
+
+% \linebuffering
\enableexperiments[fonts.compact]
-%disableexperiments[fonts.accurate]
+% \enableexperiments[fonts.accurate]
% \enabledirectives[fonts.injections.method=advance] % tricky ... not all xoffsets are advance robust
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 3b2f9b1a7dc..ef750c493a0 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
@@ -68,41 +68,44 @@ similar fashion as the other \TEX\ engines. Some options are accepted but have n
consequence. The following command|-|line options are understood:
\starttabulate[|l|p|]
-\DB commandline argument \BC explanation \NC \NR
+\DB commandline argument \BC explanation \NC \NR
\TB
-\NC \type{--credits} \NC display credits and exit \NC \NR
-\NC \type{--debug-format} \NC enable format debugging \NC \NR
-\NC \type{--draftmode} \NC switch on draft mode i.e.\ generate no output in \PDF\ mode \NC \NR
-\NC \type{--[no-]file-line-error} \NC disable/enable \type {file:line:error} style messages \NC \NR
-\NC \type{--[no-]file-line-error-style} \NC aliases of \type {--[no-]file-line-error} \NC \NR
-\NC \type{--fmt=FORMAT} \NC load the format file \type {FORMAT} \NC\NR
-\NC \type{--halt-on-error} \NC stop processing at the first error\NC \NR
-\NC \type{--help} \NC display help and exit \NC\NR
-\NC \type{--ini} \NC be \type {iniluatex}, for dumping formats \NC\NR
-\NC \type{--interaction=STRING} \NC set interaction mode: \type {batchmode}, \type {nonstopmode},
- \type {scrollmode} or \type {errorstopmode} \NC \NR
-\NC \type{--jobname=STRING} \NC set the job name to \type {STRING} \NC \NR
-\NC \type{--kpathsea-debug=NUMBER} \NC set path searching debugging flags according to the bits of
- \type {NUMBER} \NC \NR
-\NC \type{--lua=FILE} \NC load and execute a \LUA\ initialization script \NC\NR
-\NC \type{--[no-]mktex=FMT} \NC disable/enable \type {mktexFMT} generation with \type {FMT} is
- \type {tex} or \type {tfm} \NC \NR
-\NC \type{--nosocket} or \type{--no-socket} \NC disable the \LUA\ socket library \NC\NR
-\NC \type{--socket} \NC enable the \LUA\ socket library \NC\NR
-\NC \type{--output-comment=STRING} \NC use \type {STRING} for \DVI\ file comment instead of date (no
- effect for \PDF) \NC \NR
-\NC \type{--output-directory=DIR} \NC use \type {DIR} as the directory to write files to \NC \NR
-\NC \type{--output-format=FORMAT} \NC use \type {FORMAT} for job output; \type {FORMAT} is \type {dvi}
- or \type {pdf} \NC \NR
-\NC \type{--progname=STRING} \NC set the program name to \type {STRING} \NC \NR
-\NC \type{--recorder} \NC enable filename recorder \NC \NR
-\NC \type{--safer} \NC disable easily exploitable \LUA\ commands \NC\NR
-\NC \type{--[no-]shell-escape} \NC disable/enable system calls \NC \NR
-\NC \type{--shell-restricted} \NC restrict system calls to a list of commands given in \type
- {texmf.cnf} \NC \NR
-\NC \type{--synctex=NUMBER} \NC enable \type {synctex} \NC \NR
-\NC \type{--utc} \NC use utc times when applicable \NC \NR
-\NC \type{--version} \NC display version and exit \NC \NR
+\NC \type{--credits} \NC display credits and exit \NC \NR
+\NC \type{--debug-format} \NC enable format debugging \NC \NR
+\NC \type{--draftmode} \NC switch on draft mode i.e.\ generate no output in \PDF\ mode \NC \NR
+\NC \type{--[no-]check-dvi-total-pages} \NC exit when DVI exceeds 65535 pages (default: check) \NC \NR
+\NC \type{--[no-]file-line-error} \NC disable/enable \type {file:line:error} style messages \NC \NR
+\NC \type{--[no-]file-line-error-style} \NC aliases of \type {--[no-]file-line-error} \NC \NR
+\NC \type{--fmt=FORMAT} \NC load the format file \type {FORMAT} \NC\NR
+\NC \type{--halt-on-error} \NC stop processing at the first error\NC \NR
+\NC \type{--help} \NC display help and exit \NC\NR
+\NC \type{--ini} \NC be \type {iniluatex}, for dumping formats \NC\NR
+\NC \type{--interaction=STRING} \NC set interaction mode: \type {batchmode}, \type {nonstopmode},
+ \type {scrollmode} or \type {errorstopmode} \NC \NR
+\NC \type{--jobname=STRING} \NC set the job name to \type {STRING} \NC \NR
+\NC \type{--kpathsea-debug=NUMBER} \NC set path searching debugging flags according to the bits of
+ \type {NUMBER} \NC \NR
+\NC \type{--lua=FILE} \NC load and execute a \LUA\ initialization script \NC\NR
+\NC \type{--luadebug} \NC enable the \type{debug} library\NC\NR
+\NC \type{--[no-]mktex=FMT} \NC disable/enable \type {mktexFMT} generation with \type {FMT} is
+ \type {tex} or \type {tfm} \NC \NR
+\NC \type{--nosocket} \NC disable the \LUA\ socket library \NC\NR
+\NC \type{--no-socket} \NC disable the \LUA\ socket library \NC\NR
+\NC \type{--socket} \NC enable the \LUA\ socket library \NC\NR
+\NC \type{--output-comment=STRING} \NC use \type {STRING} for \DVI\ file comment instead of date (no
+ effect for \PDF) \NC \NR
+\NC \type{--output-directory=DIR} \NC use \type {DIR} as the directory to write files to \NC \NR
+\NC \type{--output-format=FORMAT} \NC use \type {FORMAT} for job output; \type {FORMAT} is \type {dvi}
+ or \type {pdf} \NC \NR
+\NC \type{--progname=STRING} \NC set the program name to \type {STRING} \NC \NR
+\NC \type{--recorder} \NC enable filename recorder \NC \NR
+\NC \type{--safer} \NC disable easily exploitable \LUA\ commands \NC\NR
+\NC \type{--[no-]shell-escape} \NC disable/enable system calls \NC \NR
+\NC \type{--shell-restricted} \NC restrict system calls to a list of commands given in \type
+ {texmf.cnf} \NC \NR
+\NC \type{--synctex=NUMBER} \NC enable \type {synctex} \NC \NR
+\NC \type{--utc} \NC use utc times when applicable \NC \NR
+\NC \type{--version} \NC display version and exit \NC \NR
\LL
\stoptabulate
@@ -135,6 +138,10 @@ The file names for output files that are generated automatically are created by
attaching the proper extension (\type {log}, \type {pdf}, etc.) to the found
\prm {jobname}. These files are created in the directory pointed to by \type
{--output-directory}, or in the current directory, if that switch is not present.
+If \type{--output-directory} is not empty, its value it's copied to the
+\type{TEXMF_OUTPUT_DIRECTORY} env. variable; if it's empty, the value of
+\type{TEXMF_OUTPUT_DIRECTORY} is the value of the output directory.
+
Without the \type {--lua} option, command line processing works like it does in
any other \WEBC|-|based typesetting engine, except that \LUATEX\ has a few extra
@@ -147,10 +154,11 @@ in the following order:
\startitem
First, it will parse the command line as usual, but it will only interpret a
- small subset of the options immediately: \type {--safer}, \type {--nosocket}
- (\type {--no-socket}), \type {--socket}, \type {--[no-]shell-escape}, \type
- {--enable-write18}, \type {--disable-write18}, \type {--shell-restricted},
- \type {--help}, \type {--version}, and \type {--credits}.
+ small subset of the options immediately: \type {--safer}, \type {--nosocket},
+ \type {--no-socket},
+ \type {--socket}, \type {--[no-]shell-escape}, \type {--enable-write18}, \type
+ {--disable-write18}, \type {--shell-restricted}, \type {--help}, \type
+ {--version}, and \type {--credits}.
\stopitem
\startitem
@@ -162,8 +170,8 @@ in the following order:
\startitem
Then it checks the various safety switches. You can use those to disable some
- \LUA\ commands that can easily be abused by a malicious document. At the
- moment, \type {--safer} \type {nil}s the following functions:
+ \LUA\ commands that can easily be abused by a malicious document. Currently
+ \type {--safer} nils the following functions:
\blank
@@ -174,8 +182,8 @@ in the following order:
\type {spawn} \type {setenv}
\type {rename} \type {remove} \type {tmpdir} \NC \NR
\NC \type {io} \NC \type {popen} \type {output} \type {tmpfile} \NC \NR
- \NC \type {lfs} \NC \type {rmdir} \type {mkdir} \type {chdir} \type {lock}
- \type {touch} \NC \NR
+ \NC \type {lfs} \NC \type {rmdir} \type {mkdir} \type {mkdirp} \type {chdir}
+ \type {lock} \type {touch} \NC \NR
\LL
\stoptabulate
@@ -186,11 +194,27 @@ in the following order:
Finally, it disables the \type {socket} library unconditionally (but not the
\type {mime} library which is always available).
+
+ From version 1.18.0 and if \KPATHSEA\ is used, with the exception of \type{debug.traceback}
+ the \type{debug} library is not enabled by default; it can be enabled with the \type
+ {--luadebug} switch. The \type{debug} library is always enabled in shell-escape mode.
+
+ Also from version 1.18.0 and if \KPATHSEA\ is used, the functions
+ \type{os.rename},\type{os.remove}, \type{lfs.attributes}, \type{lfs.chdir},
+ \type{lfs.lock_dir}, \type{lfs.dir}, \type{lfs.link}, \type{lfs.mkdir}, \type{lfs.mkdirp},
+ \type{lfs.rmdir}, \type{lfs.symlinkattributes}, \type{lfs.touch}
+ return \type{true} if both \type{kpse.in_name_ok_silent_extended} and
+ \type{kpse.out_name_ok_silent_extended} validate the pathname;
+ \type{lfs.attributes}, \type{lfs.dir} and \type{lfs.symlinkattributes} are validated
+ only against \type{kpse.in_name_ok_silent_extended}.
+
+
+
\stopitem
\startitem
When \LUATEX\ starts it sets the \type {locale} to a neutral value. If for
- some reason you use \type {os.locale}, you need to make sure you \type {nil}
+ some reason you use \type {os.setlocale}, you need to make sure you \type {nil}
it afterwards because otherwise it can interfere with code that for instance
generates dates. You can ignore the \type {locale} with:
@@ -198,19 +222,19 @@ in the following order:
os.setlocale(nil,nil)
\stoptyping
- The \type {--nosocket} (\type {--no-socket}) option makes the socket library
- unavailable, so that \LUA\ cannot use networking; the \type {--socket} option
+ The \type {--nosocket} or \type {--no-socket} option makes the socket library
+ unavailable, so that \LUA\ cannot use networking. The \type {--socket} option
makes the socket library available.
- The switches \type {--[no-]shell-escape}, \type {--[enable|disable]-write18},
- and \type {--shell-restricted} have the same effects as in \PDFTEX, and
- additionally make \type {io.popen()}, \type {os.execute}, \type {os.exec},
- \type {os.kpsepopen} and \type {os.spawn} adhere to the requested option.
+ The switches \type {--[no-]shell-escape}, \type {--[enable|disable]-write18}, and
+ \type {--shell-restricted} have the same effects as in \PDFTEX, and additionally
+ make \type {io.popen()}, \type {os.execute}, \type {os.exec}, \type {os.kpsepopen}
+ and \type {os.spawn} adhere to the requested option.
- By default the socket library is not enabled: one can enable it with with
- \type {--socket} or with \type {--shell-escape} (but without \type
- {--shell-restricted}) and disable it with \type {--nosocket} (\type
- {--no-socket}) or unconditionally with \type {--safer}.
+ By default the socket library is not enabled: one can enable it with with \type
+ {--socket} or with \type {--shell-escape} (but without \type {--shell-restricted})
+ and disable it with \type {--nosocket} (or \type {--no-socket}) or unconditionally
+ with \type {--safer}.
In case of conflictual options, the most restrictive wins.
@@ -260,6 +284,12 @@ finished: in order to initialize the built|-|in \KPATHSEA\ library properly,
check \type {--progname}, or \type {--ini} and \type {--fmt}, if \type
{--progname} is missing.
+From version 1.17.1, in \DVI\ mode the new commandline switch \type {--check-dvi-total-pages},
+enabled by default, checks that the total number of pages does not exceeds 65535,
+and in case the run abort. This breaks the compatibility with \PDFTEX\ where, as in \TEX,
+when the total number of pages is greater than 65535 the file will lie. The previous behaviour
+can be restored with \type {--[no-]check-dvi-total-pages}.
+
\stopsubsection
\stopsection
@@ -353,11 +383,12 @@ instance, when we started with \LUATEX\ we added some helpers to the \type
{lfs.isdir} and \type {lfs.isfile} were speedy and better variants of what could
be done with \type {lfs.attributes}. The additional function \type
{lfs.shortname} takes a file name and returns its short name on \type {win32}
-platforms. Finally, for non|-|\type {win32} platforms only, we provided \type
-{lfs.readlink} that takes an existing symbolic link as argument and returns its
-name. However, the \type {lfs} library evolved so we have dropped these in favour of
-pure \LUA\ variants. The \type {shortname} helper is obsolete and now just
-returns the name.
+platforms; \type{lfs.mkdirp} is like \type{lfs.mkdir} but make parent directories
+as needed (it is a \LUA\ wrapper function). Finally, for non|-|\type {win32}
+platforms only, we provided \type {lfs.readlink} that takes an existing symbolic
+link as argument and returns its name. However, the \type {lfs} library evolved so
+we have dropped these in favour of pure \LUA\ variants. The \type {shortname}
+helper is obsolete and now just returns the name.
\stopsubsection
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 2dd4a8bf1d1..00b0b2ea544 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
@@ -73,7 +73,7 @@
\startdocument
[manual=Lua\TeX,
status=stable,
- version=1.16]
+ version=1.18]
\startnotmode[*export]
\component luatex-titlepage
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/math/math-tweaks.tex b/Master/texmf-dist/doc/context/sources/general/manuals/math/math-tweaks.tex
index 6a775688d20..4845b254204 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/math/math-tweaks.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/math/math-tweaks.tex
@@ -1595,7 +1595,7 @@ mechanism as radicals (roots) but from the other edge.
\starttexdefinition ActuarianTest #1
\NC #1
\NC \switchtobodyfont[#1]
- $\bar{A}^1_{x:\rannuity{n}}^^{2}__{\rannuity{m}}$
+ $\bar{A}^1_{x:\rannuity{n}}^^^{2}___{\rannuity{m}}$
\NC \NR
\stoptexdefinition
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 50a38fc0fb8..6ca822fce06 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
@@ -11,13 +11,8 @@
columns=2,
title=MathML in \ConTeXt]
-\startmode[atpragma]
- \setupbodyfont[lucidanova]
-\stopmode
-
-\startnotmode[atpragma]
- \setupbodyfont[palatino]
-\stopnotmode
+\setupbodyfont
+ [palatino]
\setupbodyfont
[10pt]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/eutypon-gr-e-blog-21-02-13-why-i-do-not-like-luatex.png b/Master/texmf-dist/doc/context/sources/general/manuals/musings/eutypon-gr-e-blog-21-02-13-why-i-do-not-like-luatex.png
new file mode 100644
index 00000000000..3975957a430
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/eutypon-gr-e-blog-21-02-13-why-i-do-not-like-luatex.png
Binary files differ
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-assumptions.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-assumptions.tex
new file mode 100644
index 00000000000..20c82fc38b0
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-assumptions.tex
@@ -0,0 +1,141 @@
+% language=us runpath=texruns:manuals/musings
+
+\startcomponent musings-assumptions
+
+\environment musings-style
+
+\startchapter[title={Strange assumptions}]
+
+% \startsection[title={Introduction}]
+% \stopsection
+
+Below I will collect some of the questions and remarks|-|turned|-|questions that
+keep popping up and start annoying me, especially when they come from people who
+should know better (being involved in development themselves). I'm always puzzled
+why these things come up, especially by people who are no user and should not
+waste time on commenting on \CONTEXT.
+
+\startsubsubject[title={All these versions, \CONTEXT\ keep changing, so what's next?}]
+
+Sure, we're now at the third version, \MKII, \MKIV\ and \LMTX, but there is is
+some progression in this. The first version evolved from \TEX\ to \ETEX\ to
+\PDFTEX\ (but also could handle \XETEX\ and \ALEPH). But in order to get things
+done better we moved on to \LUATEX\ and because that is a \CONTEXT\ related
+project it made sense to split the code base which made us end up with a frozen
+stable \MKII\ and an evolving|-|with|-|\LUATEX\ \MKIV. Then there was a demand
+for a stable \LUATEX\ for usage otherwise which in turn lead to the \LUAMETATEX\
+project and its related \CONTEXT\ evolution \LMTX. So, yes, this macro package
+keeps changing. And it this bad? Don't other macro packages evolve? And why do
+users of other packages bother anyway? I never heard a \CONTEXT\ user complain
+either. By the way, how do other macro packages actually count and distinguish
+versions?
+
+\stopsubject
+
+\startsubsubject[title={Why is \CONTEXT\ so slow?}]
+
+Because I seldom hear complaints from users about performance, why do users of
+other macro packages find reason to even bother. In \MKII\ we immediately started
+with a high level keyword driven interface so that came with a price. But quite
+some effort was put into making it as fast and efficient as possible. Fortunately
+for \CONTEXT\ users the \MKIV\ version became faster over time, in spite of it
+using a 32 bit engine (which comes at a price). Even better is that \LMTX\ with
+\LUAMETATEX\ has gained a lot over \MKIV. But then, I guess, other macro packages
+that use \LUATEX\ are also fast, so maybe the claims that \CONTEXT\ is much
+slower than other macro packages still hold. I'm not going to check it, and I bet
+\CONTEXT\ users don't care.
+
+\stopsubject
+
+\startsubsubject[title={Why does \CONTEXT\ (even) needs a runner.}]
+
+Indeed, because we don't want users to be bothered with managing runs right from
+the start it came with a program (\MODULA2) and later a script (\PERL\ followed
+up by \RUBY) that checks if an additional run is needed because of some change in
+the table of contents, references, the index, abbreviations, positioning, etc.
+Index sorting was done too so there was no further dependency. We though that
+was actually a good thing. With \LUATEX\ and \LUAMETATEX\ all that became even
+more integrated because \LUA\ was used. The runner(s) also made it possible to
+ship additional scripts without the need for potentially clashing applications in
+the ever growing \TEX\ ecosystem. Interesting is that ridiculing \CONTEXT\ for
+script dependency was never complemented by ridiculing other macro packages that
+nowadays seem to depend on scripts (with some even using \LUATEX\ which
+originates in the \CONTEXT\ domain).
+
+\stopsubject
+
+\startsubsubject[title={Why does \CONTEXT\ organizes files that way?}]
+
+\CONTEXT\ sticks quite well to the \TEX\ Directory Structure, so what is the
+problem here?. Yes, we needed some granularity (e.g.\ for \METAPOST) but later
+that just became normal. And indeed we optionally let users use a flat directory
+structure for fonts but that's normally in the users own local tree. Oh, and in
+\MKIV\ and \LMTX\ we use our own file database (actually also in \MKII\ at some
+point), just because (definitely at that time) it was way faster and we needed
+more features. The same is true for the font database, \UTF\ encoded hyphenation
+patterns, and so on. Can it be that we're often just ahead of the pack?
+
+Let's nor forget to complain about the fact that \MKIV\ and \LMTX\ use a cache
+but so do lots or programs: just think browsers of some scripting language
+ecosystems. And that was introduced right after we started with \MKIV\ and hasn't
+changed much at all. Users expect no less. And other macro packages are free not to
+use the cache (for e.g.\ fonts).
+
+\stopsubject
+
+\startsubsubject[title={The authors of \CONTEXT\ don't care about compatibility, do they?}]
+
+You're joking, right? Surely some features became sort of obsolete when we moved
+to \MKIV, like encodings. But if users like to stick to them, they can. Do you
+really think that user like us to drop compatibility? Maybe it fits some
+narrative to spread that story. Of course, we make things better if we can, and
+the interfaces have always permitted upgrades and extensions. There are
+definitely cases when (maybe due to user demand) something new gets added that
+then evolves towards a stable state, so yes, there can be code in flux. But that
+is natural. Should we just assume that other macro packages don't evolve, never
+have bugs, don't break anything, never fix broken things immediately? Maybe. And
+complaining about \CONTEXT\ evolving is none of its non|-|users business anyway.
+
+\stopsubject
+
+\startsubsubject[title={Is \CONTEXT\ commercial?}]
+
+This is one of the strangest questions (or remarks). We use \CONTEXT\ ourself and
+using it in a job is by definition commercial use. Are all other \TEX ies only
+using \TEX\ macro packages in the free time, as hobby? I'm pretty sure that more
+money is made by competing package users and I'm also sure that most of the time
+involved in creating \CONTEXT\ (and \LUAMETATEX\ for that matter) is not covered
+by income. Using the fact that \CONTEXT\ is developed by a (small) company excuse
+for lack of development elsewhere is about as lame as it can get. Much
+development is done without us needed it, but because we like doing it, because
+of the challenge.
+
+\stopsubject
+
+\startsubsubject[title={Should I use \CONTEXT\ for math?}]
+
+Of course, because that's what \TEX\ is good at. It you are forced to use a
+specific macro package for its math abilities, just do so. If you want to move on
+or want consistent interfaces, maybe \CONTEXT\ is for you. We don't care. Trust
+your eyes more than assumed standards or ways of doing math typesetting.
+
+\stopsubject
+
+\startsubsubject[title={Why is the format file so much larger than for other packages?}]
+
+The answer is simple: we have an integrated system, so we have plenty macros and
+with each token taking 8 bytes (data and link) that adds up. And for \MKIV\ and
+\LMTX\ there also \LUA\ code involved as well as a rather large character
+database. In \LUATEX\ the format file is compressed (and also zipped) and in
+\LUAMETATEX\ is it is a bit more compressed but now zipped; still the \LMTX\
+format file is smaller than the \MKIV\ one. We let those who complain wonder why
+that is. We also let users of other macro packages wonder if loading a ton of
+stuff later on doesn't accumulate to a similar or larger memory footprint. And, as
+with many critics: make sure to check every few years if that other macro package
+hasn't catched up and can be criticized the same way.
+
+\stopsubject
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-deserved.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-deserved.tex
new file mode 100644
index 00000000000..5d16fd92840
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-deserved.tex
@@ -0,0 +1,356 @@
+% language=us runpath=texruns:manuals/musings
+
+% \enableexperiments[fonts.compact]
+
+\startcomponent musings-deserved
+
+\environment musings-style
+
+\startchapter[title={We deserved it}]
+
+\startsection[title={Introduction}]
+
+Among the first macros we cooked up are the ones that we used to typeset
+chemistry. They come under the \PPCHTEX, and it was mostly done by Hans, Ton and
+Tobias. Over time rendering structures by \PICTEX\ got replaced by \PSTRICKS\ and
+later \METAPOST. When we moved to \MKIV\ all that got reimplemented, this time by
+Hans and Alan and we stuck to \METAPOST. We actually also updated the syntax and,
+because old documents were supposed to be rendered by \MKII\ we took the liberty
+to sacrifice some compatibility for a more complete and consistent feature set.
+However we never came to updating the existing manual and the new one became work
+in progress. We didn't really needed the code and Alan, who did need it, knew
+what was there anyway.
+
+Then Mikael had some questions and it pushed me into manual mode: upgrade the old
+one and combine it with the pending new one. That also made me wonder if we could
+now benefit from some new features in the math engine, which in turn could
+simplify the code base. This is typically something that takes weeks instead of
+hours so better do it right from the start. And, while at it, one then of course
+ends up in looking (again) at arrows (or more specifically: stackers) and from
+that to \UNICODE, which in turn is good for some introspection.
+
+\stopsection
+
+\startsection[title={Implementation}]
+
+Among the (old) complications in dealing with chemistry are the following:
+
+\startitemize[packed]
+\startitem
+ Simple inline chemical formulas (snippets) of the kind \ic { U ___92 ^^^ 238
+ ^ +} where scripts need to be properly vertically aligned and an upright font
+ is used.
+\stopitem
+\startitem
+ In running text one wants to use \ic {A + B -> C} but also \ic {A + B <-> C}
+ or \ic {A + B <=> C}.
+\stopitem
+\startitem
+ Even more symbolic representations might be on the wish list, think of
+ \ic {A - B -- C --- D}.
+\stopitem
+\stopitemize
+
+There is more but these examples demonstrate a few features: we need prescripts,
+proper spacing, line breaks at preferred spots, and some symbols.
+
+\start
+
+\setupalign[profile]
+% \showglyphs \showmakeup[boxes] \showstruts
+\setupmathstackers[reverse][strut=no]
+
+\startitemize[packed]
+\startitem
+ And of course one also wants to annotate like \ic {A + B ->{here} C} but also
+ \ic {A + B <->{}{there} C} or \ic {A + B <=>{where}{every} C} where the
+ arrows stretch with the text.
+\stopitem
+\startitem
+ It would be nice if we can also use the advanced alignment options that are
+ available in math but discussing this is beyond this musing.
+\stopitem
+\stopitemize
+
+\stop
+
+\stopsection
+
+\startsection[title=Unicode]
+
+Implementing the above has never been that hard but just became a little easier
+in \LMTX. However, when doing that I wondered if there were more than the already
+present symbols to be taken care of. And so I did a search on the internet for
+\quotation {unicode and chemistry}. One of the first hits was \quotation {Five
+symbols used in chemistry L2/23-193}, a request for some more arrows. One can
+search the web for it and see if it is still around. When staring at I wondered a
+bit about the descriptions:
+
+\starttyping
+BALANCED EQUILIBRIUM ARROW
+EQUILIBRIUM ARROW LYING TOWARD THE RIGHT
+EQUILIBRIUM ARROW LYING TOWARD THE LEFT
+REACTION DOES NOT PROCEED
+STANDARD STATE SYMBOL
+\stoptyping
+
+When later I discussed this with Mikael we came to the conclusion that \quote
+{LYING} probably means \quote {LEANING} but we're not chemists so we can be
+wrong. The proposed rendering of the first three boils down to arrows with half a
+tip, also known as harpoons: long left and right pointing ones stacked for the
+first and long over short ones for the other two.
+
+\startlinecorrection
+\setupmathstackers[mathematics][strut=no]
+\startcombination[nx=3,ny=1]
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox to 2cm{$\mrightharpoonup {\hskip2cm}{}$}
+ \ruledhbox to 2cm{$\mleftharpoondown{\hskip1cm}{}\hss$}
+ }} {}
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox to 2cm{$\mrightharpoonup {\hskip2cm}{}$}
+ \ruledhbox to 2cm{$\mleftharpoondown{\hskip2cm}{}$}
+ }} {}
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox to 2cm{$\mleftharpoonup{\hskip2cm}{}$}
+ \ruledhbox to 2cm{\hss$\mrightharpoondown{\hskip1cm}{}$}
+ }} {}
+\stopcombination
+\stoplinecorrection
+
+There are several observation to make here. First of all, there is a whole bunch
+of arrows (stacked and single) that bare descriptions mentioning them being
+arrows. There is no meaning in them. One can even wonder why some are there. So,
+in order to be in sync with that it makes more sense to add a few more harpoons.
+Cooking up names like this serves no purpose.
+
+If we look at the proposed shapes (which are actually different from those used
+in \TEX\ packages that are references) one can actually wonder about the way
+these are supposed to stretch. The short variant is not different from existing
+double harpoons in which case the meaning is lost. Then when we go longer we get
+this empty space and then we should wonder how the extensible should kick in: how
+do the left- and rightmost fixed glyphs and the one or two middle repeated ones
+behave?
+
+\startlinecorrection
+\setupmathstackers[mathematics][strut=no]
+\startcombination[nx=3,ny=1]
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox to 1cm{$\mrightharpoonup {\hskip1cm}{}$}
+ \ruledhbox to 1cm{$\mleftharpoondown{\hskip1cm}{}\hss$}
+ }} {}
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox to 1cm{$\mrightharpoonup {\hskip1cm}{}$}
+ \ruledhbox to 1cm{$\mleftharpoondown{\hskip1cm}{}$}
+ }} {}
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox to 1cm{$\mleftharpoonup{\hskip1cm}{}$}
+ \ruledhbox to 1cm{\hss$\mrightharpoondown{\hskip1cm}{}$}
+ }} {}
+\stopcombination
+\stoplinecorrection
+
+Why don't we just use the next three? After all, as with math, how we interpret
+symbols depends on how we define them to be read. Sometimes Mikael and I get a
+good laugh over some of the shapes bound to math code points and we're sure that
+some legend is needed when using them.
+
+\startlinecorrection
+\setupmathstackers[mathematics][strut=no]
+\startcombination[nx=3,ny=1]
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox to 2cm{$\mleftrightharpoons{\hskip2cm}{}$}
+ }} {}
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox to 2cm{$\mrightharpoonup {\hskip2cm}{}$}
+ }} {}
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox to 2cm{$\mleftharpoondown{\hskip2cm}{}\hss$}
+ }} {}
+\stopcombination
+\stoplinecorrection
+
+Of course there are and can be conventions but getting some agreement is not
+trivial. We only have to look at \UNICODE\ math to see some issues, like:
+
+\startitemize[packed]
+\startitem
+ The repertoire of symbols is large but to a large extent somewhat arbitrary:
+ what was known (or assumed) to be used got in there. There is a difference
+ between a left, right and even middle bar, just like there is a left and
+ right brace.
+\stopitem
+\startitem
+ There are alphabets but they come with holes. We're not supposed to
+ distinguish between a Plank constant \quote {h} and variable \quote {h}. We
+ can distinguish the greek uppercase \type {A} from a latin \type {A} so
+ mathematicians are less convincing.
+\stopitem
+\startitem
+ One can define extensible fences with components but not all of them. There
+ are no constructors for arrows. Some likely come from old encodings but
+ why add these and not be consistent.
+\stopitem
+\stopitemize
+
+Plugging a hole in an alphabet is doable. Adding some missing snippets for fences
+is also no big deal, just because we have a limited set. Making bars consistent
+also is not hard. But I don't see it happen soon. After all, we're decades along
+the road and no one bothered much about it till now, and above all, it will never
+be complete. I wonder if there ever has been a good analysis, extensive
+description and a watertight arguing from the \TEX\ community about what should
+go in \UNICODE\ and fonts. It was easy to point to existing fonts and the names
+used in macro packages and that shows.
+
+To the above we can add:
+
+\startitemize[packed]
+\startitem
+ There are some combinations of arrows and e.g.rules missing that could have
+ made adding composed constructs easier when there is demand for that. After
+ all, this is what existing characters are also used for. And these chemistry
+ ones fit into this.
+\stopitem
+\stopitemize
+
+Our solution is to just accept that the \TEX\ community got what it deserved: a
+bit of chaos, unreliable cur'n'paste support, symbols but no meaning, imperfect
+\UNICODE\ coverage and therefore imperfect coverage in fonts. The good news is
+that we can adapt. But we have to be honest: it is not perfect.
+
+\stopsection
+
+\startsection[title=How about]
+
+As mentioned we have a problem with base glyphs versus extensibles and these
+combined hooked things are bad for that. In the chemistry macros the first four
+are the ones that we always had and the last two are examples of how we can
+render the two leaning extras.
+
+\starttabulate[|c||c||]
+\NC \type {<->} \NC \ic {A + B <-> C}\NC \type {<-->} \NC \ic {A + B <--> C} \NC \NR
+\NC \type {->} \NC \ic {A + B -> C}\NC \type {-->} \NC \ic {A + B --> C} \NC \NR
+\NC \type {<-} \NC \ic {A + B <- C}\NC \type {<--} \NC \ic {A + B <-- C} \NC \NR
+\NC \type {<=>} \NC \ic {A + B <=> C}\NC \type {<==>} \NC \ic {A + B <==> C} \NC \NR
+\ML
+\NC \type {=>} \NC \ic {A + B => C}\NC \type {==>} \NC \ic {A + B ==> C} \NC \NR
+\NC \type {<=} \NC \ic {A + B <= C}\NC \type {<==} \NC \ic {A + B <== C} \NC \NR
+\stoptabulate
+
+Watch the longer should arrow. Not al fonts have it as extensible, which
+indicates that not that much thought has been put in usage patterns. That said,
+more interesting would be to use something like this, where we fake a character
+from two existing arrows:
+
+\startlinecorrection
+\switchtobodyfont[cambria]
+\definemathextensible [mathematics] [mleftarrowdashed] ["21E0]
+\definemathextensible [mathematics] [mrightarrowdashed] ["21E2]
+\setupmathstackers[mathematics][strut=no]
+\startcombination[nx=4,ny=1]
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox{$\mrightarrow {}{}$}
+ \ruledhbox{$\mleftarrowdashed{}{}$}
+ }} {}
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox{$\mrightarrow{}{}$}
+ \ruledhbox{$\mleftarrow {}{}$}
+ }} {}
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox{$\mrightarrowdashed{}{}$}
+ \ruledhbox{$\mleftarrow {}{}$}
+ }} {}
+ {\vbox{\offinterlineskip\glyphscale2000
+ \ruledhbox{$\mrightarrowdashed{}{}$}
+ \ruledhbox{$\mleftarrowdashed {}{}$}
+ }} {}
+% {\vbox{\offinterlineskip\glyphscale2000
+% \ruledhbox to 2cm{$\mrightarrow {\hskip2cm}{}$}
+% \ruledhbox to 2cm{$\mleftarrowdashed{\hskip2cm}{}$}
+% }} {}
+% {\vbox{\offinterlineskip\glyphscale2000
+% \ruledhbox to 2cm{$\mrightarrow{\hskip2cm}{}$}
+% \ruledhbox to 2cm{$\mleftarrow {\hskip2cm}{}$}
+% }} {}
+% {\vbox{\offinterlineskip\glyphscale2000
+% \ruledhbox to 2cm{$\mrightarrowdashed{\hskip2cm}{}$}
+% \ruledhbox to 2cm{$\mleftarrow {\hskip2cm}{}$}
+% }} {}
+% {\vbox{\offinterlineskip\glyphscale2000
+% \ruledhbox to 2cm{$\mrightarrowdashed{\hskip2cm}{}$}
+% \ruledhbox to 2cm{$\mleftarrowdashed {\hskip2cm}{}$}
+% }} {}
+\stopcombination
+\stoplinecorrection
+
+However, not all math fonts provide these dashed arrows and therefore here we
+have to use Cambria (here). And even if it has such dashed hashes, they don't
+come with an extensible. I just want to point out that by looking at what we
+already have, it might make more sense to extend some (combinations) of those.
+
+It is good to notice that these arrows come with qualifications like \quotation
+{code for undetermined script}, so one can wonder how much they relate to math.
+Actually the fact that we have these holes in alphabets already indicates that
+math is not really seen as script. Occasionally (old) scripts get added and they
+get lots of code points, while one can argue for sharing there too, but maybe
+their status is higher than the status of math. In \OPENTYPE\ fonts math is seen
+as script but that's because it is basically a selector. One can actually argue
+for chemistry as a math language in fonts.
+
+The main point I want to make here is that adding some new symbol that is
+somewhere used but never made it in \UNICODE\ in the first place needs some
+thought. Especially when used in a setting of formulas, where size matters.
+
+\stopsection
+
+\startsection[title=Also]
+
+In \CONTEXT\ we have stackers: text above and|/|or below an extensible, or
+extensibles above and|/|or below text. The mentioned arrows are using this
+mechanism. However, when playing with \type {\iff}, \typ {\implies} and \typ
+{impliedby} in math mode, we noticed some spacing side effects. Originally these
+double arrows got skips around them but that interfered with our alignment
+mechanism. However, that could be solved without much hassle by letting the
+commands check the nature (class) of the previous atom (an indication of being at
+the start of a next alignment line). In the end that we decided that an extra
+\quote {implication} class was more flexible than adding glue. More interesting
+was the observation that in Latin Modern and some other math fonts these arrows
+have different dimensions, which leads to yet another alignment issue.
+
+Again that could be solved by taking the usage into account but one can wonder
+why the opportunity was lost to make the glyphs consistent with each other, read:
+come up with a proper analysis of requirements based on decades of \TEX\ usage.
+At least there could have been recommended alternates. But wait, aren't
+alternates kind of bad as they demand user intervention (choices)? Sure, but
+there are more examples of alternates, take the \quote {\dotlessi} (dotless i).
+It has a textual code point but is not in the math alphabets, so one needs
+alternates as way out (and yes, fonts then have a blackboard and fraktur dotless
+i).
+
+One can argue that these are visual aspects, but with arrows as well as symbols,
+we have ended up in a somewhat curious inconsistent situation: there are no
+established command names for the single arrows, so there we speak \type
+{\..arrow..} while for some there are names, like \type {\iff}. The same is true
+for characters like the dotless i and j. Some mathematicians use these in the
+same way as some hard- and software vendors put an \quote {i} in front of a
+product name, but in order to get it one has to communicate in terms of \type
+{\dotless.} or somthing with an \type {i} in the macro name.
+
+\stopsection
+
+\startsection[title=Conclusion]
+
+To come back to updating chemistry. It makes no sense to add much more.
+Implementing the left- and right leaning is easy with existing hooks so this is
+what we will do. Proper math fonts have these and how likely is it that existing
+math fonts get new ones? If it ever comes to more chemistry in \UNICODE\ a
+handful of them will not help much. It is probably not that hard to find an
+existing symbol that can act as standard state symbol. In fact, some code points
+have several additional descriptions so we could just add some to existing one.
+It's not like we have gone over the top with doing that for math yet.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-dontusetex.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-dontusetex.tex
new file mode 100644
index 00000000000..f8f81079525
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-dontusetex.tex
@@ -0,0 +1,201 @@
+% language=us runpath=texruns:manuals/musings
+
+\startcomponent musings-dontusetex
+
+\environment musings-style
+
+\setupquotation[style=italic]
+
+\startchapter[title={Don't use \TEX !}]
+
+Occasionally I run into a web post that involves \LUATEX\ and it is sometimes
+surprising what nonsense one can read. Now, I normally don't care that much but
+there are cases where I feel that a comment is justified. Partly because I'm one
+of the developers, but also because I'm involved in user groups.
+
+In this particular case the title of a (small) blog post was \quotation {Why I do
+not like luaTeX!} and the website announced itself ambitiously as \quote {DIGITAL
+TYPOGRAPHY NEWS}. Normally I assume that in such a case it is a general site
+about typesetting and that the author has not much experience or insight in the
+already ancient \TEX\ typesetting system. However, the \URL\ is:
+
+\starttyping
+eutypon.gr/e-blog/index.php/2021/02/13/why-i-do-not-like-luatex/
+\stoptyping
+
+which happens to be the Greek User Groups portal. So why do I feel the need to
+reflect on this? Why do I even care? The answer is simple: because user groups
+should inform their (potential) users correctly. Another reason is that I'm
+involved in the program that is disliked, and yet another one is that there is a
+suggestion that language support is bad in \LUATEX, while actually hyphenation
+patterns are very well maintained by Mojca and Arthur who are also actively
+involved in the community around the mentioned engine.
+
+\startplacefigure[location=page,number=no,title={\type {eutypon.gr/e-blog/index.php/2021/02/13/why-i-do-not-like-luatex/}}]
+ \externalfigure
+ [eutypon-gr-e-blog-21-02-13-why-i-do-not-like-luatex.png]
+ [width=\textwidth]
+\stopplacefigure
+
+Let's start with the title. For sure one might not like a specific program, but
+when it involves one of the mainstream \TEX\ engines, it should at least be clear
+that it's a personal opinion. Because no name is mentioned, we can assume that
+this is the opinion of the Greek user group as a whole. The text starts with
+\quotation {Most people speak with good words about luaTeX.} and the \quote {most}
+in that sentence sort of puts the author in a small group, which should trigger
+using a bit more careful title. Now I know a couple of users who use \LUATEX\
+(with \CONTEXT) for typesetting Greek, and we can assume that they are among the
+people who speak those good words: typesetting Greek just works.
+
+More good news is that \quotation {They seem to like things it can do that no
+other TeX derived systrem can do.} This might invite potential users to take a
+closer look at the system, especially because we already know that most people
+are positive. In 2021 one should keep in mind that, although the \LUATEX\ engine
+is around for more than a decade, the level of support can differ per macro
+package which is why \PDFTEX\ is still the most widespread used \TEX\ variant:
+much \TEX\ usage relates to writing (scientific articles) in English so one
+doesn't really need an \UNICODE\ engine. I always say: don't change a good
+working workflow if you have no reason; use what makes you feel comfortable. Only
+use \LUATEX\ if you have a reason. There is plenty of good and positive advice to
+be given.
+
+With \quotation {Personally, I do not care about these features but yesterday a
+friend told me that he wanted to write something in Greek with luaLaTeX.} the
+author steps over his or her personal rejection of the engine and enters the
+help|-|a|-|friend mode. \quotation {And what’s the catch, one may ask. The
+problem is that luaLaTeX does not load any hyphenation patterns but the default
+ones. So one needs to load them.} I'm not sure why this is a catch. It actually
+is a feature. One drawback of the traditional \TEX\ engines is that one needs to
+preload the hyphenation patterns. Before memory was bumped, that often meant
+creating format files for a subset of languages, and when memory became plenty it
+meant preloading dozens of patterns by default. The good news is that in all
+these cases the macro package takes care of that. In the case of \LUATEX\ no
+patterns need to be preloaded so it might even be that \LATEX\ doesn't have any
+preloaded but, not being a user, I didn't check that.
+
+This all makes the next sentence puzzling: \quotation {In TeX one uses a command
+like the follolwing one : \type {\language\l@monogreek}, where \type
+{\l@monogreek} is numerical value assigned to each language contained in the
+format.} Now, I'm no expert on \LATEX\ but I'm pretty sure that the \type {@}
+sign is not a letter by default. I'm also pretty sure that there is some high
+level interface to enable a language, and in the case of \LUATEX\ being used that
+mechanism will load the patterns runtime. I bet it will also deal with making
+sure other language specific properties are set. Therefore the \quotation {This
+is well documented in the TeXbook.} is somewhat weird: original \TEX\ only had
+one language and later versions could deal with more, but plain \TEX\ has no
+\type {\l@monogreek} command. It doesn't sound like the best advice to me.
+
+Just to be sure, I unpacked all the archives in the most recent \TEXLIVE\ \DVD\
+and grepped for that command in \type {tex} and \type {sty} files and surprise:
+in the \LATEX\ specific style file \typ {/tex/xelatex/xgreek/xgreek.sty} there is
+a line \typ {\language \l@monogreek \else \HyphenRules{monogreek}\fi} which to me
+looks way to low level for common users to figure out, let alone that it's a file
+for \XETEX\ so bound to a specific engine. Further grepping for \type {{greek}}
+gave hits for \LATEX's babel an there are Greek files under the \type
+{polyglossia} directory so I bet that Arthur (who once told me he was reponsible
+for languages) deals with Greek there. Even I, as a \CONTEXT\ user who never use
+\LATEX\ and only know some things by rumor (like the fact that there is something
+like polyglossia at all) could help a new user with some suggestions of where to
+look, just by googling for a solution. But explicitly using the \type {\language}
+primitive is not one of them. Okay, in \CONTEXT\ the \type {\language [greek]}
+command does something useful, but we're not talking about that package here, if
+only because it relates to \LUATEX\ development, which as we will see later is a
+kind of inner circle.
+
+So, picking up on the blog post, in an attempt to get Greek working in \LATEX\
+the author got online but \quotation {Now despite the fact that I spent a few
+hours searching for information on how to load specific hyphenation patterns, I
+could not find anything!} It might have helped to search for \type {lualatex
+greek} because that gives plenty of hits. And maybe there are even manuals out
+there that explain which of the packages in the \TEX\ tree to load in order to get
+it working. Maybe searching \CTAN\ or \TEXLIVE\ helps too. Maybe other user
+groups have experts who can help out. No matter what you run into, I don't think
+that the average user expects to find a recipe for installing and invoking
+patterns. Just for the record, the \LUATEX\ manual has a whole chapter on
+language support, but again, users can safely assume that the macro package that
+they use hides those details. Actually, if users were supposed to load patterns
+using a unique id, they are likely to end up in the modern Greek versus ancient
+Greek, as well as Greek mixed with English or other languages situations. That
+demands some more in depth knowledge to deal with, in any macro package and with
+any engine. You can add a bit of \UNICODE\ and \UTF-8\ or encodings in the mix
+too. Suggesting to consult the \TEX book is even a bit dangerous because one then
+also ends up in an eight bit universe where font encodings play a role, while
+\LUATEX\ is an \UNICODE\ engine that expects \UTF\ and uses \OPENTYPE\ fonts.
+And, while languages seem to be a problem for the author and his|/|her friend,
+fonts seem to be an easy deal. In my experience it's more likely that a user runs
+into font issues because modern fonts operate on multiple axis: script, language
+and features.
+
+Maybe the confusion (or at that time accumulated frustration) is best summarized
+by \quotation {Moreover, I could not find any information on how one loads a lua
+package (i.e., some external lua package that is available in the TeX
+installation).} Well, again I'm sure that one can find some information on
+\LATEX\ support sites but as I already said: language support is so basic in a
+macro package that users can use some simple command to enable their favorite
+one. So, when \quotation {People know that they can load a LaTeX package with the
+\type {\usepackage} command but I have no information on how to load lua code.}
+the first part is what matters: \LUA\ files are often part of a package and
+thereby they get loaded by the package, also because often stand|-|alone usage
+makes not much sense.
+
+It is absolutely no problem if someone doesn't like (or maybe even hates)
+\LUATEX, but it's a different matter when we end up in disinformation, and even
+worse in comments that smell like conspiracy: there is an inner circle of
+\LUATEX\ developers and \quotation {Practically, this means that if one is not
+part of the inner circle of luaTeX developers, then she cannot really know what
+is really going on.} Really? Is this how user groups educate their users? There
+are manuals written, plenty of articles published, active mailing lists,
+presentations given, and there is support on platforms like Stack Exchange. And
+most of that (the development of \LUATEX\ included) is done by volunteers in
+their spare time, for free. Of course the groups of core developers are small but
+that is true for any development. History (in the \TEX\ community) has
+demonstrated that this is the only way to make progress at all, simply because
+there are too many different views on matters, and also because the time of
+volunteers is limited. It is the end result what counts and when that is properly
+embedded in the community all is fine. So we have some different engines like
+\TEX, \PDFTEX, \LUATEX, etc., different macro packages, specialized engines like
+those dealing with large \CJK\ fonts, all serving a different audience from the
+same ecosystem. Are these all secretive inner circles with bad intentions to
+confuse users?
+
+The blog post ends with \quotation {And this is exactly the reason why I do not
+like luaTeX.} to which I can only comment that I already long ago decided not to
+waste any time on users who in their comments sound like they were forced to use
+a \TEX\ system (and seem to dislike it, so probably are better off with Microsoft
+Word, but nevertheless like to bark against some specific \TEX\ tree), who
+complain about manuals not realizing that their own contributions might be rather
+minimalistic, maybe even counter productive, or possibly of not much use to
+potential users anyway. I also ignore those who love to brag about the many bugs,
+any small number suits that criterium, without ever mentioning how bugged their
+own stuff is, etc. If your ego grows by disregarding something you don't even
+use, it's fine for me.
+
+So why do I bother writing this? Because I think it is a very bad move and signal
+of a user group to mix personal dislike, whatever the reason is, with informing
+and educating users. If a group is that frustrated with developments, it should
+resolve itself. On the other hand, it fits well in how todays communication
+works: everyone is a specialist, which get confirmed by the fact that many
+publish (also on topics they should stay away from) on the web without fact
+checking, and where likes and page hits are interpreted as a confirmation of
+one's expertise. Even for the \TEX\ community there seems to be no escaping from
+this.
+
+The objectives of \TEX\ user groups shift, simply because users can find
+information and help online instead of at meetings and in journals. The physical
+\TEX\ distributions get replaced by fast downloads but they are definitely under
+control of able packagers. Maybe a new task of user groups is to act as guardian
+against disinformation. Of course one then has to run into these nonsense blogs
+(or comments on forums) and such but that can partly be solved by a mechanism
+where readers can report this. A user group can then try to make its own
+information better. However, we have a problem when user groups themselves are
+the source of disinformation. I see no easy way out of this. We can only hope
+that such a port drowns in the ocean of information that is already out there to
+confuse users. In the end a good and able \TEX\ friend is all you need to get
+going, right? The blog post leaves it open if the Greek text ever got typeset
+well. If not, there's always \CONTEXT\ to consider, but then one eventually ends
+up with \LUAMETATEX\ which might work on the author as another \quotation {\nl
+rode lap op een stier} as we say in Dutch.
+
+\stopchapter
+
+\stoptext
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-history.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-history.tex
new file mode 100644
index 00000000000..28e9575192c
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-history.tex
@@ -0,0 +1,294 @@
+% language=us runpath=texruns:manuals/musings
+
+\startcomponent musings-history
+
+\environment musings-style
+
+\startchapter[title={All those \TEX's}]
+
+\startlines \setupalign[flushright]
+Hans Hagen
+Hasselt NL
+February 2020
+\stoplines
+
+% \startsection[title=Introduction]
+% \stopsection
+
+This is about \TEX, the program that is used as part of the large suite of
+resources that make up what we call a \quote {\TEX\ distribution}, which is used
+to typeset documents. There are many flavors of this program and all end with
+\type {tex}. But not everything in a distribution that ends with these three
+characters is a typesetting program. For instance, \type {latex} launches the a
+macro package \LATEX, code that feeds the program \type {tex} to do something
+useful. Other formats are Plain (no \type {tex} appended) or \CONTEXT\ (\type
+{tex} in the middle. Just take a look at the binary path of the \TEX\
+distribution to get an idea. When you see \type {pdftex} it is the program, when
+you see \type {pdflatex} it is the macro package \LATEX\ using the \PDFTEX\
+program. You won't find this for \CONTEXT\ as we don't use that model of mixing
+program names and macro package names.
+
+Here I will discuss the programs, not the macro packages that use them. When you
+look at a complete \TEXLIVE\ installation, you will see many \TEX\ binaries. (I
+will use the verbatim names to indicate that we're talking of programs). Of
+course there is the original \type {tex}. Then there is its also official
+extended version \type {etex}, which is mostly known for adding some more
+primitives and more registers. There can be \type {aleph}, which is a stable
+variant of \type {omega} meant for handling more complex scripts. When \PDF\
+became popular the \type {pdftex} program popped up: this was the first \TEX\
+engine that has a backend built in. Before that you always had to run an
+additional program to convert the native \DVI\ output of \TEX\ into for instance
+\POSTSCRIPT. Much later, \type {xetex} showed up, that, like \OMEGA, dealt with
+more complex scripts, but using recent font technologies. Eventually we saw \type
+{luatex} enter the landscape, an engine that opened up the internals with the
+\LUA\ script subsystem; it was basically a follow up on \type {pdftex} and \type
+{aleph}.
+
+The previous paragraph mentions a lot of variants and there are plenty more. For
+\CJK\ and especially Japanese there are \type {ptex}, \type {eptex}, \type
+{uptex}, \type {euptex}. Parallel to \type {luatex} we have \type {luajittex} and
+\type {luahbtex}. As a follow up on the (presumed stable) \type {luatex} the
+\CONTEXT\ community now develops \type {luametatex}. A not yet mentioned side
+track is \NTS\ (New \TEX\ system), a rewrite of good old \TEX\ in \JAVA, which in
+the end didn't take off and was never really used.
+
+There are even more \TEX's and they came and went. There was \type {enctex} which
+added encoding support, there were \type {emtex} and \type {hugeemtex} that
+didn't add functionality but made more possible by removing some limits on memory
+and such; these were quite important. Then there were vendors of \TEX\ systems
+that came up with variants (some had extra capabilities), like \type {microtex},
+\type {pctex}, \type {yandytex} and \type {vtex} but they never became part of
+the public effort.
+
+For sure there are more, and I know this because not so long ago, when I cleaned
+up some of my archives, I found \type {eetex} (extended \ETEX), and suddenly
+remembered that Taco Hoekwater and I indeed had experimented with some extensions
+that we had in mind but that never made it into \ETEX. I had completely forgotten
+about it, probably because we moved on to \LUATEX. It is the reason why I wrap
+this up here.
+
+In parallel there have been some developments in the graphic counterparts. Knuts
+\type {metafont} program got a \LUA\ enhanced cousin \type {mflua} while \type
+{metapost} (aka \type {mpost} or \type {mp}) became a library that is embedded in
+\LUATEX\ (and gets a follow up in \LUAMETATEX). I will not discuss these here.
+
+If we look back at all this, we need to keep in mind that originally \TEX\ was
+made by Don Knuth for typesetting his books. These are in English (although over
+time due to references he needed to handle different scripts than Latin, be it
+just snippets and not whole paragraphs). Much development of successors was the
+result of demands with respect to scripts other than Latin and languages other
+than English. Given the fact that (at least in my country) English seems to
+become more dominant (kids use it, universities switch to it) one can wonder if
+at some point the traditional engine can just serve us as well.
+
+The original \type {tex} program was actually extended once: support for mixed
+usage of multiple languages became possible. But apart from that, the standard
+program has been pretty stable in terms of functionality. Of course, the parts
+that made the extension interface have seen changes but that was foreseeable. For
+instance, the file system hooks into the \KPSE\ library and one can execute
+programs via the \type {\write} command. Virtual font technology was also an
+extension but that didn't require a change in the program but involved
+postprocessing the \DVI\ files.
+
+The first major \quote {upgrade} was \ETEX. For quite a while extensions were
+discussed but at some point the first version became available. For me, once
+\PDFTEX\ incorporated these extensions, it became the default. So what did it
+bring? First of all we got more than 256 registers (counters, dimensions, etc.).
+Then there are some extra primitives, for instance \type {\protected} that
+permits the definition of unexpandable macros (although before that one could
+simulate it at the cost of some overhead) and convenient ways to test the
+existence of a macro with \type {\ifdefined} and \type {\ifcsname}. Although not
+strictly needed, one could use \type {\dimexpr} for expressions. A probably
+seldom used extension was the (paragraph bound) right to left typesetting. That
+actually is a less large extension than one might imagine: we just signal where
+the direction changes and the backend deals with the reverse flushing. It was
+mostly about convenience.
+
+The \OMEGA\ project (later followed up by \ALEPH) didn't provide the additional
+programming related primitives but made the use of wide fonts possible. It did
+extend the number of registers, just by bumping the limits. As a consequence it
+was much more demanding with respect to memory. The first time I heard of \ETEX\
+and \OMEGA\ was at the 1995 euro\TEX\ meeting organized by the \NTG\ and I was
+sort of surprised by the sometimes emotional clash between the supporters of
+these two variants. Actually it was the first time I became aware of \TEX\
+politics in general, but that is another story. It was also the time that I
+realized that practical discussions could be obscured by nitpicking about
+speaking the right terminology (token, node, primitive, expansion, gut, stomach,
+etc.) and that one could best keep silent about some issues.
+
+The \PDFTEX\ follow up had quite some impact: as mentioned it had a backend built
+in, but it also permitted hyperlinks and such by means of additional primitives.
+It added a couple more, for instance for generating random numbers. But it
+actually was a research project: the frontend was extended with so called
+character protrusion (which lets glyphs hang into the margin) and expansion (a
+way to make the output look better by scaling shapes horizontally). Both these
+extensions were integrated in the paragraph builder and are thereby extending
+core code. Adding some primitives to the macro processor is one thing, adapting a
+very fundamental property of the typesetting machinery is something else. Users
+could get excited: \TEX\ renders a text even better (of course hardly anyone
+notices this, even \TEX\ users, as experiments proved).
+
+In the end \OMEGA\ never took off, probably because there was never a really
+stable version and because at some time \XETEX\ showed up. This variant was first
+only available on Apple computers because it depends on third party libraries.
+Later, ports to other systems showed up. Using libraries is not specific for
+\XETEX. For instance \PDFTEX\ uses them for embedding images. But, as that is
+actually a (backend) extension it is not critical. Using libraries in the
+frontend is more tricky as it adds a dependency and the whole idea about \TEX\
+was that is is independent. The fact that after a while \XETEX\ switched
+libraries is an indication of this dependency. But, if a user can live with that,
+it's okay. The same is true for (possibly changing) fonts provided by the
+operating system. Not all users care too strongly about long term compatibility.
+In fact, most users work on a document, and once finished store some \PDF\ copy
+some place and then move on and forget about it.
+
+It must be noted that where \ETEX\ has some limited right to left support,
+\OMEGA\ supports more. That has some more impact on all kinds of calculations in
+the machinery because when one goes vertical the width is swapped with the
+height|/|depth and therefore the progression is calculated differently.
+
+Naturally, in order to deal with scripts other than Latin, \XETEX\ did add some
+primitives. I must admit that I never looked into those, as \CONTEXT\ only added
+support for wide fonts. Maybe these extensions were natural for \LATEX, but I
+never saw a reason to adapt the \CONTEXT\ machinery to it, also because some
+\PDFTEX\ features were lacking in \XETEX\ that \CONTEXT\ assumed to be present
+(for the kind of usage it is meant for). But we can safely say that the impact of
+\XETEX\ was that the \TEX\ community became aware that there were new font
+technologies that were taking over the existing ones used till now. One thing
+that is worth noticing is that \XETEX\ is still pretty much a traditional \TEX\
+engine: it does for instance \OPENTYPE\ math in a traditional \TEX\ way. This is
+understandable as one realizes that the \OPENTYPE\ math standard was kind of
+fuzzy for quite a while. A consequence is that for instance the \OPENTYPE\ math
+fonts produced by the \GUST\ foundation are a kind of hybrid. Later versions
+adopted some more \PDFTEX\ features like expansion and protrusion.
+
+I skip the Japanese \TEX\ engines because they serve a very specific audience and
+provide features for scripts that don't hyphenate but use specific spacing and
+line breaks by injecting glues and penalties. One should keep in mind that before
+\UNICODE\ all kinds of encodings were used for these scripts and the 256
+limitations of traditional \TEX\ were not suited for that. Add to that demands
+for vertical typesetting and it will be clear that a specialized engine makes
+sense. It actually fits perfectly in the original idea that one could extend
+\TEX\ for any purpose. It is a typical example of where one can argue that users
+should switch to for instance \XETEX\ or \LUATEX\ but these were not available
+and therefore there is no reason to ditch a good working system just because some
+new (yet unproven) alternative shows up a while later.
+
+We now arrive at \LUATEX. It started as an experiment in 2005 where a \LUA\
+interpreter was added to \PDFTEX. One could pipe data into the \TEX\ machinery
+and query some properties, like the values of registers. At some point the
+project sped up because Idris Hamid got involved. He was one of the few \CONTEXT\
+users who used \OMEGA\ (which it actually did support to some extent) but he was
+not satisfied with the results. His oriental \TEX\ project helped pushing the
+\LUATEX\ project forward. The idea was that by opening up the internals of \TEX\
+we could do things with fonts and paragraph building that were not possible
+before. The alternative, \XETEX\ was not suitable for him as it was too bound to
+what the libraries provides (rendering then depends on what library gets used and
+what is possible at what time). But, dealing with scripts and fonts is just one
+aspect of \LUATEX. For instance more primitives were added and the math machinery
+got an additional \OPENTYPE\ code path. Memory constraints were lifted and all
+became \UNICODE\ internally. Each stage in the typesetting process can be
+intercepted, overloaded, extended.
+
+Where the \ETEX\ and \OMEGA\ extensions were the result of many years of
+discussion, the \PDFTEX, \XETEX\ and \LUATEX\ originate in practical demands.
+Very small development teams that made fast decisions made that possible.
+
+Let's give some more examples of extensions in \LUATEX. Because \PDFTEX\ is the
+starting point there is protrusion and expansion, but these mechanisms have been
+promoted to core functionality. The same is true for embedding images and content
+reuse: these are now core features. This makes it possible to implement them more
+naturally and efficiently. All the backend related functionality (literal \PDF,
+hyperlinks, etc) is now collected in a few extension primitives and the code is
+better isolated. This took a bit of effort but is in my opinion better. Support
+for directions comes from \OMEGA\ and after consulting with its authors it was
+decided that only four made sense. Here we also promoted the directionality to
+core features instead of extensions. Because we wanted to serve \OMEGA\ users too
+extended \TFM\ fonts can be read, not that there are many of them, which fits
+nicely into the whole machinery going 32~instead of 8~bits. Instead of the \ETEX\
+register model, where register numbers larger than 255 were implemented
+differently, we adopted the \OMEGA\ model of just bumping 256 to 65536 (and of
+course, 16K would have been sufficient too but the additional memory it uses can
+be neglected compared to what other programs use and|/|or what resources users
+carry on their machines).
+
+The modus operandi for extending \TEX\ is to take the original literate \WEB\
+sources and define change files. The \PDFTEX\ program already deviated from that
+by using a monolithic source. But still \PASCAL\ is used for the body of core
+code. It gets translated to \CCODE\ before being compiled. In the \LUATEX\
+project Taco Hoekwater took that converted code and laid the foundation for what
+became the original \LUATEX\ code base.
+
+Some extensions relate to the fact that we have \LUA\ and have access to \TEX's
+internal node lists for manipulations. An example is the concept of attributes.
+By setting an attribute to a value, the current nodes (glyphs, kerns, glue,
+penalties, boxes, etc) get these as properties and one can query them at the
+\LUA\ end. This basically permits variables to travel with nodes and act
+accordingly. One can for instance implement color support this way. Instead of
+injecting literal or special nodes that themselves can interfere we now can have
+information that does not interfere at all (apart from maybe some performance
+hit). I think that conceptually this is pretty nice.
+
+At the \LUA\ one has access to the \TEX\ internals but one can also use specific
+token scanners to fetch information from the input streams. In principle one can
+create new primitives this way. It is always a chicken|-|egg question what works
+better but the possibility is there. There are many such conceptual additions
+in \LUATEX, which for sure makes it the most \quote {aggressive} extension of
+\TEX\ so far. One reason for these experiments and extensions is that \LUA\
+is such a nice and suitable language for this purpose.
+
+Of course a fundamental part of \LUATEX\ is the embedded \METAPOST\ library. For
+sure the fact that \CONTEXT\ integrates \METAPOST\ has been the main reason for
+that.
+
+The \CONTEXT\ macro package is well adapted to \LUATEX\ and the fact that its
+users are always willing to update made the development of \LUATEX\ possible.
+However, we are now in a stage that other macro packages use it so \LUATEX\ has
+entered a state where nothing more gets added. The \LATEX\ macro package now
+also supports \LUATEX, although it uses a variant that falls back on a library to
+deal with fonts (like \XETEX\ does).
+
+With \LUATEX\ being frozen (of course bugs will be fixed), further exploration
+and development is now moved to \LUAMETATEX, again in the perspective of
+\CONTEXT. I will not go into details apart from saying that is is a lightweight
+version of \LUATEX. More is delegated to \LUA, which already happened in
+\CONTEXT\ anyway, but also some extra primitives were added, mostly to enable
+writing nicer looking code. However, a major aspect is that this program uses a
+lean and mean code base, is supposed to compile out of the box, and that sources
+will be an integral part of the \CONTEXT\ code base, so that users are always in
+sync.
+
+So, to summarize: we started with \type {tex} and moved on to \type {etex} and
+\type {pdftex}. At some point \type {omega} and \type {xetex} filled the
+\UNICODE\ and script gaps, but it now looks like \type {luatex} is becoming
+popular. Although \type {luatex} is the reference implementation, \LATEX\
+exclusively uses \type {luahbtex}, while \CONTEXT\ has a version that targets at
+\type {luametatex}. In parallel, the \type {[e][u][p]tex} engines fill the
+specific needs for Japanese users. In most cases, good old \type {tex} and less
+old \type {etex} are just shortcuts to \type {pdftex} which is compatible but has
+the \PDF\ backend on board. That 8 bit engine is not only faster than the more
+recent engines, but also suits quite well for a large audience, simply because
+for articles, thesis, etc. (written in a Latin script, most often English) it
+fits the bill well.
+
+I deliberately didn't mention names and years as well as detailed pros and cons.
+A user should have the freedom to choose what suits best. I'm not sure how well
+\TEX\ would have evolved or will evolve in these days of polarized views on
+operating systems, changing popularity of languages, many (also open source)
+projects being set up to eventually be monetized. We live in a time where so
+called influencers play a role, where experience and age often matters less than
+being fancy or able to target audiences. Where something called a standard today
+is replaced quickly by a new one tomorrow. Where stability and long term usage of
+a program is only a valid argument for a few. Where one can read claims that one
+should use this or that because it is todays fashion instead of the older thing
+that was the actually the only way to achieve something at all a while ago. Where
+a presence on facebook, twitter, instagram, whatsapp, stack exchange is also an
+indication of being around at all. Where hits, likes, badges, bounties all play a
+role in competing and self promotion. Where today's standards are tomorrow's
+drawbacks. Where even in the \TEX\ community politics seem to creep in. Maybe you
+can best not tell what is your favorite \TEX\ engine because what is hip today
+makes you look out of place tomorrow.
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-introduction.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-introduction.tex
index dc5eb28892c..a973de1ff02 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-introduction.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-introduction.tex
@@ -19,13 +19,21 @@ for more than a decade but is still used without problems) I wrote \quotation
{Stability}.
Many of the thoughts in these articles are influenced by discussions with my
-colleagues Ton Otten and Kees van Marle. Operating in a similar arena, they
-provide me the reflection needed to sort out my thoughts on these matters.
+colleagues Ton Otten and Kees van Marle, users and developers. Operating in a
+similar arena, they provide me the reflection needed to sort out my thoughts on
+these matters.
+
+The order in this document is not chronological. In the meantime we also put some
+development related stories in this collection, just because they have to fit in
+somewhere.
+
+Not all musings are checked and copy|-|edited so let me know if there are errors
+and typos in them.
\startlines
Hans Hagen
Hasselt NL
-2017\endash 1028
+2017\endash 2023+
\stoplines
\stopchapter
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-manuals.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-manuals.tex
new file mode 100644
index 00000000000..170517a5ab3
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-manuals.tex
@@ -0,0 +1,236 @@
+% language=us runpath=texruns:manuals/musings
+
+% \showfontkerns
+
+% \setupalign[granular]
+
+\startcomponent musings-manuals
+
+\environment musings-style
+
+\startchapter[title={About manuals}]
+
+\startsection[title={Introduction}]
+
+I'm always puzzled when I read that someone wonders if \CONTEXT\ is still up to
+date or maintained because some manual has a timestamp of a decade ago. I'm also
+puzzled by some rants you can run into when searching the web. In the next few
+paragraphs I'll comment on this.
+
+\stopsection
+
+\startsection[title={Stability}]
+
+Say that you're an enthusiastic user of console commands like \type {ls} (\type
+{dir}), \type {cp} (\type {copy}) or maybe \type {ssh}, \type {rsync}, \type
+{curl}. How often do you consult a manual on how they evolve? And say that you,
+for some reason, do consult a manual, there is a good change that it is
+pretty old. Does that mean that the commands are obsolete? The binaries probably
+get fixed for bugs but the interface stays the same, which is what you expect.
+Every time we generate a zip for the \CONTEXT\ distribution, the related website
+also gets generated, using a bunch of \XML\ files that get transformed to \HTML\
+using \XSLT\ and a pretty ancient version of \type {xsltproc} (why should I
+update). I never check for a new manual as it keeps doing the job. And additional
+manuals and reports get added.
+
+So, once some functionality is stable, and a lot of macro code in \CONTEXT\ is
+just that, there is no need to update a manual! Putting a new time stamp on it is
+basically fake updating. And often the more introductionary kind of manuals don't
+need to be updated at all, apart from maybe cultural changes that demand a
+(political correct) update. Them being a bit old and not being updated is
+actually a good thing as it signals stability.
+
+It is worth mentioning that the \CONTEXT\ distribution is not the only source of
+information. There are manuals written by others and there is the Wiki. All is
+the work of volunteers and updating all that depends on how much time one can
+allocate.
+
+\stopsection
+
+\startsection[title={Excuses}]
+
+It is a fact that \CONTEXT\ evolves. New functionality gets added and some
+mechanism get extended. Often these are described in dedicated manuals or
+articles that end up in collections, and there are plenty of them in the
+distribution. For some reason those complaining about a beginners manual with an
+old time stamp don't check if there is more, and there is quite some more! Don't
+only look at the \CONTEXT\ garden (the wiki) but also keep an eye on what gets
+distributed. Some users are very good in track of what gets added, because
+sometimes I get fixes for typos send within a few hours after uploading a zip.
+
+We appreciate that other users point out that writing manuals takes time and that
+indeed our time is not without limits. If I could sit down and write manuals
+whole day, and it would get paid, I might do it. But it is a fact that
+development of \CONTEXT\ is not paid for at all. I can work on it in company time
+but much happens in spare time. Most development is a gamble on future use or
+done because we want to be complete or because code can be improved. So, writing
+a manual then closely relates to what we like doing: it determines the topics and
+priorities. If something gets explored and ends up in new functionality then that
+gets documented in the process. It is the fun factor that drives it. The same is
+true for \LUATEX\ development.
+
+So, we have as valid excuse that new manuals relate to (new) functionality and
+old ones stay as they are. Don Knuth remarks somewhere that writing a manual as
+part of the development is a good thing. We fully agree with that.
+
+\stopsection
+
+\startsection[title={Cutting edge}]
+
+Does an old manual indicate that nothing happens? Definitely not. Over a decade
+of \LUATEX\ development is closely related to \CONTEXT\ and there is plenty of
+reporting about that. Does that mean that we need to rewrite manuals? No,
+existing functionality remains. And of course users are free to come up with
+more detailed manuals (which they seldom do). Some developments get published
+in user group journals but we don't publish much about specific \CONTEXT\ features
+and usage because it's hard to do that for a diverse audience.
+
+Currently we have what is called \CONTEXT\ \MKXL\ (aka \LMTX), but we also have
+the prelude to that, \MKIV, and the frozen predecessor \MKII. Apart from changes in
+technology (most noticeably fonts and encodings) the functionality is accumulative:
+most old manuals (unless they are specialized into old school fonts for instance)
+apply to the latest greatest version.
+
+It is a misunderstanding that the development of \CONTEXT, \LUATEX\ and
+\LUAMETATEX\ is somehow funded by projects that we do. This is not true. We can
+apply both in projects but as we charge by the hour (or day) no customer ever
+sees development on the bill. Of course during a project we can gain on
+efficiency (so then development pays back) and because we know the system style
+writing is efficient too. In fact, in most cases our customers don't know or care
+what tool we use because tools are expected to be part of the deal. Most projects
+we can (and could) only do because we can use \CONTEXT\ and that is a side effect
+of the fact that we do develop beforehand. We're often the only technically
+and|/|or affordable way out. It's a chicken|-|egg issue: we have a tool and
+therefore get a project. We never get a projects where we can develop a tool. No
+one pays for \TEX\ development or at least no one ever came to us with specific
+\TEX\ related demands. It looks like the world takes it for granted that \TEX\ is
+just there. \footnote {There are a few subcomponents of \CONTEXT\ that were
+partially sponsored by users and we do have some support contracts that permit
+experiments and development.}
+
+The reason for \CONTEXT\ being cutting edge (in terms of \TEX) is that we like
+challenges, that users demand features that are interesting to explore and that
+we've been part of the \TEX\ scenery for a while now. We just like that.
+
+It's good to know that \CONTEXT\ was and is developed as a toolkit. We started
+long ago because we needed a way to quickly create and update reports of meetings
+that we chaired. Next we needed a way to efficiently produce high quality
+education materials (of various kind) and support maintenance of sets of related
+(quality assurance) manuals. We could have used wordstar, wordperfect or msword
+but liked the \TEX\ way much more. As said, most customers didn't even know or
+care what tool was used because the (often highly interactive \PDF) outcome
+mattered most. In fact, we would not be interested in this kind of work if we
+were forced to use clumsy tools, but for sure a lot can be done with those as
+well.
+
+\stopsection
+
+\startsection[title={Continuity}]
+
+Most development happens at \PRAGMA\ by me (Hans) with help from my two
+colleagues (Ton and Kees) and the community (Aditya, Alan, Mikael, Mojca, Luigi,
+Hraban, Taco, Thomas, Tomas, Willi, Wolfgang, and others). \footnote {More names
+could be here as I write this in 2022.} I won't mention those on the mailing list
+who contribute with ideas, testing and support, but they can't be missed. The
+biggest danger for continuity is a polluted code base where everyone just pushed
+code into a repository. So this is closely guarded. A user patch might work well
+for that user but can break something else.
+
+With \TEX\ you need to keep in mind that once a solution works there is no need
+to update code or manuals. As long as there is a working \LUATEX\ (\LUAMETATEX)
+binary you're fine. Maybe if some specific fonts are used, a filename might need
+to be adapted.
+
+An example. When we added a new \XML\ subsystem to \CONTEXT\ \MKIV\ we knew that
+some day we could use it. We now uses it in a few projects and I'm pretty sure
+that we would not do these projects otherwise as it would demand writing quite
+complex \XSLT\ style sheets that then would have to be applied to thousands of
+files per run. To some extend what is available in \CONTEXT\ sort of drives the
+kind of work you look for. That said: if you consider using \CONTEXT\ for simple
+or complex documents, either of not in a collection, either or not using \TEX\ or
+\XML\ input you can be assured that this will work (and might even get better)
+because we use it ourselves.
+
+If you want to get an idea about development, just look at the (five) documents
+that describe the development of \LUATEX\ (\LUAMETATEX). Locating them in the
+distribution is a good opportunity to explore the documents. They will show you
+what happened the last decade(s) and give you some trust in \CONTEXT. Or come to
+a \CONTEXT\ meeting and meet those involved.
+
+\stopsection
+
+% \startsection[title={Stay away}]
+%
+% There are reasons why you won't find us (me) on some social media. First of all
+% we like using the mailing list. It puts some time between what one thinks or
+% wants to ask and actually getting it out in the open. After all, one might regret
+% a too spontaneous complain or even rant, so it sort of protects subscribers.
+%
+% It is not that hard to search the web (say Reddit) and find someone complaining
+% about something \TEX\ (or \CONTEXT) related, including \type {f**ck} kind of
+% wording. If you're in that category, please stay away from \CONTEXT\ or try to
+% constrain yourself. It won't trigger help. Why on earth does one rant about a
+% system that one doesn't like unless maybe one is enforced to use it. We prefer 10
+% out of 10000 \TEX\ users using \CONTEXT\ over 1000 of which 990 are unhappy: use
+% another macro package and be part of the possible unhappy crowd there. We're not
+% selling a product, we're sharing a potential useful tool! Also keep in mind that
+% (as I know a bit about \TEX\ and its ecosystem) it would be very easy for me to
+% counter you if I really wanted that; it might make you look ridiculous.
+%
+% That said, we see no benefit in being on Facebook. I never look for something
+% there myself I'm too unfamiliar with it, I have nothing to share and and don't
+% look forward to keeping something up to date. There is no need for an instant
+% news channel on Whatsapp, Instagram, Telegram, Tiktok or other media that are
+% driven by advertisements and filtering user data. We could post tutorials on
+% YouTube but don't. It is already bad enough that I have to endure advertisements
+% myself, let alone that users get bombarded by unrelated crap. We could have a
+% fancy website and try to sell \CONTEXT\ \quote {professional} or present some
+% \quote {plans}, but we like to keep it simple: the site is generated when we push
+% an update and has been for decades so little work is involved in that. We don't
+% keep statistics, let alone have trackers. I see no benefit in it and I don't
+% like to waste time on that either.
+%
+% We are not on Stack Exchange but other \CONTEXT\ developers post very nice
+% \CONTEXT\ answers there. Personally I just don't like a system with likes, votes,
+% counters and somewhat persistent old (sometimes confusing) stuff. But I'm
+% thankful for others who can deal with it.
+%
+% We could have a Patreon account but that's not how we work here and from seeing
+% how it is used it would make me feel uncomfortable anyway. In a similar fashion
+% we don't see benefits in commercializing the Github repository. Those who need
+% support or and want to support development can find us if they want to.
+%
+% We have always participated in \TEX\ meetings and publish in use group journals
+% about developments and such. We also have always been pretty active in the
+% community and like it there. Just stay away from it when ranting is all you can
+% contribute.
+%
+% \stopsection
+
+\startsection[title={Closing remark}]
+
+So next time someone asks if \CONTEXT\ is maintained because some old manual
+stays around, return the question if frequently updated manuals are a sign of
+stability. Also ask if someone looked a bit in the documentation tree. The oldest
+manual in the \TEX\ world is the \TEX book that describes the oldest stable set
+of macros: plain \TEX. There are happy users out there who love that stability.
+If it were not for the wonderful personality of Don Knuth this program would
+already been forgotten. I think that long term stability and unchanged code and
+manuals are something that we need to cherish and get accustomed to, which is not
+easy in a time when a phone and its operating system are outdated as soon as you
+unbox it. It's also not easy in a time of instant communication, more and more
+confused by what is called artificial intelligent mumbling, but that's for
+another wrapup.
+
+\stopsection
+
+\startlines
+Hans Hagen
+Hasselt NL
+
+(uncorrected so there's something left to complain)
+\stoplines
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-perfection.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-perfection.tex
new file mode 100644
index 00000000000..18eeb6da5a3
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-perfection.tex
@@ -0,0 +1,124 @@
+% language=us runpath=texruns:manuals/musings
+
+\startcomponent musings-perfection
+
+\environment musings-style
+
+\startchapter[title={Do we need perfection ?}]
+
+\startsection[title={Introduction}]
+
+It doesn't take much imagination to think of a future were jobs become less
+interesting. Automation and especially machine learning will dominate more and
+more. At least in the Netherlands there is a tendency to talk in terms of jobs
+that assume \quotation {highly educated} folk, but often that is just a way to
+boost one's self esteem, of worse, to suggest that a job is very interesting. In
+this perspective the term {\em bs job} comes up. I like working with computers
+but I'm not sure if I'd choose to work with them when I were young: the
+perspective often for instance {\em scrumming through the workload} doesn't
+really attract me. Add to that the fact that todays employer tomorrow has a
+different owner and changed objectives and it becomes even less attractive.
+
+I often get the impression that the more constructive jobs are also the more
+interesting ones but alas they are not that advocated (or popular). On the
+Internet you can find plenty videos of the amazing things that humans can do.
+Incredible mechanical solutions: buildings, ships, planes, gears, waterworks,
+chips, and when you go a bit back in time you'll notice that often what we
+consider advanced today was inspired by the past (hint: search for lunar module
+computer and colossus if you're interested in the origins of computing as we know
+it today).
+
+When you read about old school typography it is clear that we are dealing with a
+craft. At some point extensive manual labor got assistance from tools: chisels,
+lead letter forms, the printing press, semi|-|automated mechanical devices like
+Monotype and Linotype but it was still craftmanship that was in demand. These
+tools made it possible to scale up.
+
+When computers came around the landscape changed. The things that could not be
+automated still demanded manual intervention but soon (at least that is what we
+noticed) the demands simply changed. When the computer cannot hyphenate well,
+just forget about it and there's always an argument to come up with. And yes,
+much of today's typesetting is not really new but comes from the (near) past. The
+Monotype 4|-|line system for math looks quite interesting and advanced. If you
+think that our emoji are hip and modern, just look at what the Aztec did.
+
+The \TEX\ system has always been a bit different because it demands some manual
+work to get things right. Of course one can use some precooked style but then
+we're not talking craftmanship. The focus is then on the content and if it looks
+kind of right all is good. It either gets retypeset \quotation {far far away} or
+when it is just pushed on the web no one bothers (it has best fit on a phone).
+
+It is really puzzling to see how little attention is paid to digitizing documents
+It is not too hard to find 150 dpi scans where the pages were scanned in an angle
+of relatively recent documents \typ
+{https://www.tug.org/docs/liang/liang-thesis.pdf}. When I finally decided to buy
+the original \CCODE\ book, a wondered why I had to pay some 60 dollar for what
+looks like either a bad scan or some low quality digital print and after a first
+glance I decided that I'll probably throw it in the paper bin some day soon
+because I can as well use some bad scan from Internet. One of my first buys with
+respect to typesetting was \quotation {Digital Typography: An Introduction to
+Type and Composition for Computer System Design} by Richard Rubinstein. That one
+was done on a Mac with MSWord in 1988 and looks better than the average document
+done by \TEX\ that students get from their teachers who were (probably) educated
+around that time. It's more about paying attention than about the tools.
+
+The idea behind \CONTEXT\ macro package is (and will be) that users themselves
+have some influence on what it does. There is no way that it can compete in the
+\TEX\ domain with precooked styles simply because the standard has been set very
+early to \LATEX\ (and \AMS\ math) and most marketing in the community targets to
+such usage. One|-|time and one|-|shot users, of whom I bet some {\em have to} use
+\TEX, but would gladly use something else, are not the audience for \CONTEXT. So
+that brings us to questions like \quotation {What are the objectives of a macro
+package like \CONTEXT ?}, \quotation {Do we need to provide perfect solutions.},
+\quotation {What do users want?}. Being forced to use (a) \TEX\ (macro package)
+is not much different from being forced to use an operating system, editor or
+programming language. In the end there has to be a \quote {click} and when it's
+there long term happy usage will often also lead to mastery and satisfaction.
+
+Another set of questions relate to how eager we should be to keep up with all
+demands. Do we really need to listen to publishers, especially when there is no
+real indication of interest in typesetting but more in growth, profit, periodical
+selling oneself. Demands change and standards come and go. A good example of a
+currently popular demand is tagging documents, but when you look at that from
+that with \TEX\ glasses on it is kind of weird. A \TEX\ based system can pretty
+well render any variant of a document and target specific needs: paper, screen,
+dedicated devices, different fonts, colors etc.\ is all pretty trivial. If a
+house is not well accessible you adapt it. If clothing doesn't fit, you shop for
+a different make. If you have an allergy you get different food. When it comes to
+documents we can distribute variants and even the source. Not doing that when
+there is demand is just laziness, unwillingness or going cheap. So, should we
+adapt, or should we be more creative with designs and target alternative (and
+multiple) media? If we don't, at least we should come up with good reasons.
+
+To go back to what I started with: how do we keep working with documents, coming
+up with solutions, playing with layout, interesting? It might as well be that in
+the future when the ratio employment versus free time also gives more room for
+figuring things out. The interaction between coming with the content and somehow
+present it using tools like \CONTEXT\ can have a positive result on the final
+product. Isn't is a nice challenge to serve a broad audience with well tuned
+documents?
+
+My impression is that the more extensive \CONTEXT\ users have enough freedom to
+use a system like that. They are probably not working at large companies or in
+large organizations that impress tools and methods. So a valid question is: how
+does a system have to look like in order to draw those users into the game and
+how does it keep them in a position that they can keep using it. We don't need
+perfect, all automated, human replacement tools, do we? We're more talking
+\quote {toolkit}, aren't we?
+
+I'd like users to come up with additional sections here. How do they use
+\CONTEXT ? What do they expect from a system like that? How should it evolve?
+Where should it stop? What challenges should it leave to the user? What can go
+and what (kind of control) should be added?
+
+\stopsection
+
+\startsection[title={Your turn}]
+
+{\em user contributions}
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-performance.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-performance.tex
new file mode 100644
index 00000000000..aad29f9ea46
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-performance.tex
@@ -0,0 +1,382 @@
+% language=us runpath=texruns:manuals/musings
+
+% \usemodule[abbreviations-smallcaps]
+
+\startcomponent musings-performance
+
+\environment musings-style
+
+\startchapter[title={Performance again}]
+
+\startlines \setupalign[flushright]
+Hans Hagen
+Hasselt NL
+Februari 2020 (public 2023)
+\stoplines
+
+\startsection[title=Introduction]
+
+In a \MAPS\ article of 2019 I tried to answer the question \quote {Is \TEX\
+really slow?}. A while after it was published on the Dutch \TEX\ mailing list a
+user posted a comment stating that in his experience the \LUATEX\ engine in
+combination with \LATEX\ was terribly slow: one page per second for a Japanese
+text. It was also slower than \PDFTEX\ with English, but for Japanese it was
+close to unusable. The alternative, using a Japanese \TEX\ engine was no option
+due to lack of support for certain images.
+
+In order to check this claim I ran a test in \CONTEXT. Even on my 8 year old
+laptop I could get 45 pages per second for full page Japanese texts (6 paragraphs
+with each 300 characters per page): 167 pages took just less than 4 seconds.
+Typesetting Japanese involves specific spacing and line break handling. So,
+naturally the question arises: why the difference. Frans Goddijn wondered if I
+could explain a bit more about that, so here we go.
+
+In the mentioned article I already have explained what factors play a role and
+the macro package is one of them. It is hard to say to what extent inefficient
+macros or a complex layout influence the runtime, but my experience is that it is
+pretty hard to get speeds as low as 1 page per second. On an average complex
+document like the \LUATEX\ manual (lots of verbatim and tables, but nothing else
+demanding apart from color being used and a unique \METAPOST\ graphic per page) I
+get at least a comfortable 20 pages per second.
+
+I can imagine that for a \TEX\ user who sees other programs on a computer do
+complex things fast, the performance of \TEX\ is puzzling. But, where for
+instance rendering videos can benefit from specific features of (video)
+processors, multiple cores, or just aggressive optimization by compilers of
+(nested) loops and manipulation of arrays of bytes, this is not the case for
+\TEX. This program processes all in sequence, there is not much repetition that
+can be optimized, it cannot exploit the processor in special ways and the
+compiler can not do that many optimizations.
+
+I can't answer why a \LATEX\ run is slower than a \CONTEXT\ run. Actually, one
+persistent story has always been that \CONTEXT\ was slow in comparison. But maybe
+it helps to know a bit what happens deep down in \TEX\ and how macro code can
+play a role in performance. When doing that I will simplify things a bit.
+
+\stopsection
+
+\startsection[title=Text and nodes]
+
+The \TEX\ machinery takes input and turns that into some representation that can
+be turned into a visual representation ending up as \PDF. So say that we have
+this:
+
+\starttyping
+hello
+\stoptyping
+
+In a regular programming language this is a string with five characters. When the
+string is manipulated it is basically still a sequence of bytes in memory. In
+\TEX, if this is meant as text, at some point the internal representation is a so
+called node list:
+
+\starttyping
+[h] -> [e] -> [l] -> [l] -> [o]
+\stoptyping
+
+In traditional \TEX\ these are actually character nodes. They have a few properties,
+like what font the character is from and what the character code is (0 up to 255).
+At some point \TEX\ will turn that list into a glyph list. Say that we have this:
+
+\starttyping
+efficient
+\stoptyping
+
+This will eventually become seven nodes:
+
+\starttyping
+[e] -> [ffi] -> [c] -> [i] -> [e] -> [n] -> [t]
+\stoptyping
+
+The ffi ligature is a glyph node which actually also keeps information about this
+one character being made from three.
+
+In \LUATEX\ it is different, and this is one of the reasons for it being slower. We
+stick to the first example:
+
+\starttyping
+[h] <-> [e] <-> [l] <-> [l] <-> [o]
+\stoptyping
+
+So, instead of pointing to the next node, we also point back to the previous: we
+have a double linked list. This means that all over the program we need to
+maintain these extra links too. They are not used by \TEX\ itself, but handy at
+the \LUA\ end. But, instead of only having the font as property there is much
+more. The \TEX\ program can deal with multiple languages at the same time and
+this relates to hyphenation. In traditional \TEX\ there are language nodes that
+indicate a switch to another language. But in \LUATEX\ that property is kept with
+each glyph node. Actually, even specific language properties like the hyphen min,
+hyphen max and the choice if uppercase should be hyphenated are kept with these
+nodes. Spaces are turned into glue nodes, and these nodes are also larger than in
+regular \TEX\ engines.
+
+So, in \LUATEX, when a character goes from the input into a node, a more complex
+data structure has to be set up and the larger data structure also takes more
+memory. That in turn means that caching (close to the \CPU) gets influenced. Add
+to that the fact that we operate on 32 bit character values, which also comes
+with higher memory demands.
+
+We mentioned that a traditional engine goes from one state of node list into
+another (the ligature building). Actually this is an integrated process: a lot
+happens on the fly. If something is put into a \type {\hbox} no hyphenation takes
+place, only ligature building and kerning. When a paragraph is typeset,
+hyphenation happens on demand, in places where it makes sense.
+
+In \LUATEX\ these stages are split. A node list is {\em always} hyphenated. This
+step as well as ligature building and kerning are {\em three} separate steps. So,
+there's always more hyphenation going on than in a traditional \TEX\ engine: we
+get more discretionary nodes and again these take more memory than before; also
+the more nodes we have, the more it will impact performance down the line. The
+reason for this is that each step can be intercepted and replaced by a \LUA\
+driven one. In practice, with modern \OPENTYPE\ fonts that is what happens: these
+are dealt with (or at least managed in) \LUA. For Japanese for sure the
+built|-|in ligature and kerning doesn't apply: the work is delegated and this
+comes at a price. Japanese needs no hyphenation but instead characters are
+treated with respect to their neighbors and glue nodes are injected when needed.
+This is something that \LUA\ code is used for so here performance is determined
+by how well the plugged in code behaves. It can be inefficient but it can also be
+so clever that it just takes a bit of time to complete.
+
+I didn't mention another property of nodes: attributes. Each node that has some
+meaning in the node list (glyphs, kerns, glue, penalties, discretionary,
+\unknown, these terms should ring bells for a \TEX\ user) have a pointer to an
+attribute list. Often these are the same for neighboring nodes, but they can be
+different. If a macro package sets 10 attributes, then there will be lists of ten
+attributes nodes (plus some overhead) active. When values change, copies are made
+with the change applied. Grouping even complicates this a little more. This has
+an impact on performance. Not only need these lists be managed, when they are
+consulted at the \LUA\ end (as they are meant as communication with that bit of
+the engine) these lists are interpreted. It all adds up to more runtime. There is
+nothing like that in traditional \TEX, but there some more macro juggling to
+achieve the same effects can cause a performance hit.
+
+\stopsection
+
+\startsection[title=Macros and tokens]
+
+When you define a macro like this:
+
+\starttyping
+\def\MyMacro#1{\hbox{here: #1!}}
+\stoptyping
+
+the \TEX\ engine will parse this as follows (we keep it simple):
+
+\starttabulate[|Tc|l|]
+\NC \string\def \NC primitive token \NC \NR
+\NC \string\MyMacro \NC user macro pointing to: \NC \NR
+\NC \char\hashasciicode 1 \NC argument list of length 1 and no delimiters \NC \NR
+\NC \char\leftbraceasciicode \NC openbrace token \NC \NR
+\NC \string\hbox \NC hbox primitive token \NC \NR
+\NC h \NC letter token h \NC \NR
+\NC e \NC letter token e \NC \NR
+\NC r \NC letter token r \NC \NR
+\NC e \NC letter token e \NC \NR
+\NC : \NC other token : \NC \NR
+\NC \NC space token \NC \NR
+\NC \char\hashasciicode 1 \NC reference to argument \NC \NR
+\NC ! \NC other token ! \NC \NR
+\NC \char\rightbraceasciicode \NC close brace token \NC \NR
+\stoptabulate
+
+The \type {\def} is eventually lost, and the meaning of the macro is stored as a
+linked list of tokens that get bound to the user macro \type {\MyMacro}. The details
+about how this list is stored internally can differ a bit per engine but the idea
+remains. If you compare tokens of a traditional \TEX\ engine with \LUATEX, the main
+difference is in the size: those in \LUATEX\ take more memory and again that impacts
+performance.
+
+\stopsection
+
+\startsection[title=Processing]
+
+Now, for a moment we step aside and look at a regular programming language, like
+\PASCAL, the language \TEX\ is written in, or \CCODE\ that is used for \LUATEX.
+The high level definitions, using the syntax of the language, gets compiled into
+low level machine code: a sequence of instructions for the \CPU. When doing so
+the compiler can try to optimize the code. When the program is executed all the
+\CPU\ has to do is fetch the instructions, and execute them, which in turn can
+lead to fetching data from memory. Successive versions of \CPU's have become more
+clever in handling this, predicting what might happen, (pre) fetching data from
+memory etc.
+
+When you look at scripting languages, again a high level syntax is used but after
+interpretation it becomes compact so called bytecode: a sequence of instructions
+for a virtual machine that itself is a compiled program. The virtual machine
+fetches the bytes and acts upon them. It also deals with managing memory and
+variables. There is not much optimization going on there, certainly not when the
+language permits dynamically changing function calls and such. Here performance
+is not only influenced by the virtual machine but also by the quality of the
+original code (the scripts). In \LUATEX\ we're talking \LUA\ here, a scripting
+language that is actually considered to be pretty fast.
+
+Sometimes bytecode can be compiled Just In Time into low level machine code but
+for \LUATEX\ that doesn't work out well. Much \LUA\ code is executed only once or
+a few times so it simply doesn't pay off. Apart from that there are other
+limitations with this (in itself impressive) technology so I will not go into
+more detail.
+
+So how does \TEX\ work? It is important to realize that we have a mix of input
+and macros. The engine interprets that on the fly. A character enters the input
+and \TEX\ has to look at it in the perspective of what it what it expects. It is
+just a character? Is it part of a control sequence that started (normally) with a
+backslash? Does it have a special meaning, like triggering math mode? When a
+macro is defined, it gets stored as a linked list of tokens and when it gets
+called the engine has to expand that meaning. In the process some actions
+themselves kind of generate input. When that happens a new level of input is
+entered and further expansion takes place. Sometimes \TEX\ looks ahead and when
+not satisfied, pushes something back into the input which again introduces a new
+level. A lot can happen when a macro gets expanded. If you want to see this, just
+add \type {\tracingall} at the top of your file: you will be surprised! You will
+not see how often tokens get pushed and popped but you can see how much got
+expanded and how often local changes get restored. By the way, here is something
+to think about:
+
+\starttyping
+\count4=123
+\advance \count4 by 123
+\stoptyping
+
+If this is in your running text, the scanner sees \type {\count} and then
+triggers the code that handles it. That code expects a register number, here that
+is the \type {4}. Then it checks if there is an optional \type {=} which means
+that it has to look ahead. In the second line it checks for the optional keyword
+\type {by}. This optional scanning has a side effect: when the next token is {\em
+not} an equal or keyword, it has to push back what it just read (we enter a new
+input level) and go forward. It then scans a number. That number ends with a
+space or \type {\relax} or something not being a number. Again, some push back
+onto the input can happen. In fact, say that instead of \type {4} we have a macro
+indicating the register number, intermediate expansion takes place. So, even
+these simple lines already involve a lot of action! Now, say that we have this
+
+\starttyping
+% \newcounter \scratchcounter % done once
+\scratchcounter 123
+\scratchcounter =123
+\advance\scratchcounter by 123
+\advance\scratchcounter 123
+\stoptyping
+
+Can you predict what is more efficient? If this operation doesn't happen
+frequently, performance wise there is no real difference between the variants
+with and without \type {=} and with and without \type {b}. This is because \TEX\
+is pretty fast in tokenizing its input and interpreting its already stored token
+lists that have these commands. But given what we said before, when you talk of
+millions of such assignments, adding the equal sign and \type {by} {\em could}
+actually be faster because there is no pushing back onto the input stack
+involved. It probably makes no sense to take this into account when writing
+macros but just keep in mind that performance is in the details.
+
+% written in 2020, the next added in Januari 2023
+
+Actually, contrary to what you might expect, \type {\scratchcounter} is not even a
+counter in \CONTEXT, and in \LUAMETATEX we can also do this:
+
+\starttyping
+% \newinteger\scratchcounter % done once
+\scratchcounter 123
+\scratchcounter =123
+\advanceby\scratchcounter 123
+\stoptyping
+
+Which means that because this counter is defined as so called \quotation
+{constant integer} it avoids some indirectness (to a counter register) and
+because \type {\advanceby} doesn't scan for a keyword the code above runs faster
+anyway.
+
+This model of expansion is very different from compiled code or bytecode. To some
+extent you can consider a list of tokens that make up a macro to be bytecode, but
+instead of a sequence of bytes it is a linked list. That itself has a penalty in
+performance. Depending on how macros expand, the engine can be hopping all over
+the token memory following that list. That means that quite likely the data that
+gets accessed is not in your \CPU\ cache and as a result performance cannot
+benefit from it apart of course from the expanding machinery itself, but that one
+is not a simple loop messing around with variables: it accesses code all over the
+place! Text gets hyphenated, fonts get applied, material gets boxed, paragraphs
+constructed, pages built. We're not moving a blob of bits around (as in a video)
+but we're constantly manipulating small amounts of memory scattered around memory
+space.
+
+Now, where a traditional \TEX\ engine works on 8 bit characters and smaller
+tokens, the 32 bit \LUATEX\ works on larger chunks. Although macro names are
+stored as single symbolic units, there are moments when its real (serialized to
+characters) name is used, for instance when with \type {\csname}. When that
+happens, the singular token becomes a list, so for instance the (stored) token
+\type {\foo} becomes a temporary three token list (actually four if you also
+count the initial reference token). Those tree tokens become three characters in
+a string that then is used in the hash lookup. There are plenty cases where such
+temporary string variables are allocated and filled. Compare:
+
+\starttyping
+\def\foo{\hello}
+\stoptyping
+
+Here the macro \type {\foo} has just a one token reference to \type {\hello}
+because that's how a macro reference gets stored. But in
+
+\starttyping
+\def\foo{\csname hello\endcsname}
+\stoptyping
+
+we have two plus five tokens to access what effectively is \type {\hello}. Each
+character token has to be converted to a byte into the assembled string. Now it
+must be said that in practice this is still pretty fast but when we have longer
+names and especially when we have \UTF8 characters in there it can come at a
+price. It really depends on how your macro package works and sometimes you just
+pay the price of progress. Buying a faster machine is then the solution because
+often we're not talking of extreme performance loss here. And modern \CPU's can
+juggle bytes quite efficiently. Actually, when we go to 64 bit architectures,
+\LUATEX's data structures fit quite well to that. As a side note: when you run a
+32 bit binary on a 64 bit architecture there can even be a price being paid for
+that when you use \LUATEX. Just move on!
+
+\stopsection
+
+\startsection[title=Management]
+
+Before we can even reach the point that some content becomes typeset, much can
+happen: the engine has to start up. It is quite common that a macro package uses
+a memory dump so that macros are not to be parsed each run. In traditional
+engines hyphenation patterns are stored in the memory dump as well. And some
+macro packages can put fonts in it. All kind of details, like upper- and
+lowercase codes can get stored too. In \LUATEX\ fonts and patterns are normally
+kept out of the dump. That dump itself is much larger already because we have 32
+bit characters instead of 8 bit so more memory is used. There are also new
+concepts, like catcode tables that take space. Math is 32 bit too, so more codes
+related to math are stored. Actually the format is so much larger that \LUATEX\
+compresses it. Anyway, it has an impact on startup time. It is not that much, but
+when you measure differences on a one page document the overhead in getting
+\LUATEX\ up and running will definitely impact the measurement.
+
+The same is true for the backend. A traditional engine uses (normally) \TYPEONE\
+fonts and \LUATEX\ relies on \OPENTYPE. So, the backend has to do more work. The
+impact is normally only visible when the document is finalized. There can be a
+slightly larger hickup after the last page. So, when you measure one page
+performance, it again pollutes the page per second performance.
+
+\stopsection
+
+\startsection[title=Summary]
+
+So, to come back to the observation that \LUATEX\ is slower than \PDFTEX. At
+least for \CONTEXT\ we can safely conclude that indeed \PDFTEX\ is faster when we
+talk about a standard English document, with \TEX\ \ASCII\ input, where we can do
+with traditional small fonts, with only some kerning and simple ligatures. But as
+soon as we deal with for instance \XML, have different languages and scripts,
+have more demanding layouts, use color and images, and maybe even features that
+we were not aware of and therefore didn't require in former times the \LUATEX\
+engine (and for \CONTEXT\ it's \LUAMETATEX\ follow up) performs way better than
+\PDFTEX. And how about support for hyper links, protrusion and expansion, tagging
+for the sake of accessibility, new layers of abstraction, etc. The impact on
+performance can differ a lot per engine (and probably also per macro package).
+So, there is no simple answer and explanation for the fact that the observed slow
+\LATEX\ run on Japanese text, apart from that we can say: look at the whole
+picture: we have more complex tokens, nodes, scripts and languages, fonts,
+macros, demands on the machinery, etc. Maybe it is just the price you are paying
+for that.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-plain.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-plain.tex
index 96396bb8162..1a33efbfe8d 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-plain.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-plain.tex
@@ -6,7 +6,9 @@
\environment musings-style
-\definetyping[narrowtyping][style=\ttx]
+\ifdefined\startnarrowtyping \else
+ \definetyping[narrowtyping][style=\ttx]
+\fi
\startchapter[title={About what \CONTEXT\ isn't}]
@@ -546,6 +548,13 @@ that those coming up with answers and remarks like that probably missed somethin
in assessing \CONTEXT. Just let users find out themselves what suits best (and
for some that actually might be plain \TEX).
+Let me make on thing clear. If you look at the documents that describe the
+development of \TEX, \METAFONT\ and the related fonts, you can only awe at what
+was done on hardware that doesn't come close to what we hold now in the palm of
+our hand. And it was done in a relative short time span. The fact that plain
+\TEX\ ran on it the way it did is amazing. Anyone who considers criticizing \TEX\
+and plain \TEX\ should think (more than) twice.
+
\stopsection
\stopchapter
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 873c652c133..8d6733031a7 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
@@ -2,7 +2,7 @@
\startenvironment musings-style
-\usemodule[abr-04]
+\usemodule[abbreviations-logos]
\setupbodyfont
[pagella]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-treasures.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-treasures.tex
new file mode 100644
index 00000000000..aaa3c4b7a1c
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-treasures.tex
@@ -0,0 +1,201 @@
+% language=us runpath=texruns:manuals/musings
+
+\startcomponent musings-treasures
+
+\environment musings-style
+
+\startchapter[title={Hidden treasures}]
+
+\startlines \setupalign[flushright]
+Hans Hagen
+Hasselt 2020
+February 2020
+\stoplines
+
+At \CONTEXT\ meetings we always find our moments to reflect on the interesting
+things that relate to \TEX\ that we have run into. Among those we discussed were
+some of the historic treasures one can run into when one looks at source files. I
+will show examples from several domains in the ecosystem and we hereby invite the
+reader to come up with other interesting observations, not so much in order to
+criticize the fantastic open source efforts related to \TEX, but just to indicate
+how decades of development and usage are reflected in the code base and usage, if
+only to make it part of the history of computing.
+
+I start with the plain \TEX\ format. At the top of that file we run into this:
+
+\starttyping[style=\ttx]
+% The following changes define internal codes as recommended
+% in Appendix C of The TeXbook:
+
+\mathcode`\^^@="2201 % \cdot
+\mathcode`\^^A="3223 % \downarrow
+\mathcode`\^^B="010B % \alpha
+\mathcode`\^^C="010C % \beta
+\mathcode`\^^D="225E % \land
+\mathcode`\^^E="023A % \lnot
+\mathcode`\^^F="3232 % \in
+...
+\mathcode`\^^Y="3221 % \rightarrow
+\mathcode`\^^Z="8000 % \ne
+\mathcode`\^^[="2205 % \diamond
+\mathcode`\^^\="3214 % \le
+\mathcode`\^^]="3215 % \ge
+\mathcode`\^^^="3211 % \equiv
+\mathcode`\^^_="225F % \lor
+\stoptyping
+
+This means that when you manage to key in one of these recommended character
+codes that in \ASCII\ sits below the space slot, you will get some math symbol,
+given that you are in math mode. Now, if you also consider that the plain \TEX\
+format is pretty compact and that no bytes are wasted,\footnote {Such definitions
+don't take additional space in the format file.} you might wonder what these
+lines do there. The answer is simple: there were keyboards out there that had
+these symbols. But, by the time \TEX\ became popular, the dominance of the \IBM\
+keyboard let those memories fade away. This is just Don's personal touch I guess.
+Of course the question remains if the sources of TAOCP contain these characters.
+
+There is another interesting hack in the plain \TEX\ file, one that actually,
+when I first looked at the file, didn't immediately made sense to me.
+
+\starttyping[style=\ttx]
+\font\preloaded=cmti9
+\font\preloaded=cmti8
+\font\preloaded=cmti7
+
+\let\preloaded=\undefined
+\stoptyping
+
+What happens here is that a bunch of fonts get defined and they all use the same
+name. Then eventually that name gets nilled. The reason that these definitions
+are there is that when \TEX\ dumps a format file, the information that comes from
+those fonts is embedded to (dimensions, ligatures, kerns, parameters and math
+related) data. It is an indication that in those days it was more efficient to
+have them preloaded (that is why they use that name) than loading them at
+runtime. The fonts are loaded but you can only access them when you define them
+again! Of course nowadays that makes less sense, especially because storage is
+fast and operating systems do a nice job at caching files in memory so that
+successive runs have font files available already.
+
+Talking of fonts, one of the things a new \TEX\ user will notice and also one of
+the things users love to brag about is ligatures. If you run the \type {tftopl}
+program on a file like \type {cmr10.tfm} you will get a verbose representation of
+the font. Here are some lines:
+
+\starttyping[style=\ttx]
+(LABEL C f) (LIG C i O 14) (LIG C f O 13) (LIG C l O 15)
+(LABEL O 13) (LIG C i O 16) (LIG C l O 17)
+(LABEL C `) (LIG C ` C \)
+(LABEL C ') (LIG C ' C ")
+(LABEL C -) (LIG C - C {)
+(LABEL C {) (LIG C - C |)
+(LABEL C !) (LIG C ` C <)
+(LABEL C ?) (LIG C ` C >)
+\stoptyping
+
+The \type {C} is followed by an \ASCII\ representation and the \type {)} by the
+position in the font \type {O} (a number) or \type {C} (a character). So,
+consider the first two lines to be a puzzle: they define the fi, ff, fl ligatures
+as well as the ffi and ffl ones. Do you see how ligatures are chained?
+
+But anyway, what do these other lines do there? It looks like \type {``} becomes
+the character in the backslash slot and \type {''} the one in the double quote.
+Keep in mind that \TEX\ treats the backslash special and when you want it, it
+will be taken from elsewhere. But still, these two ligatures look familiar: they
+point to slots that have the left and right double quotes.\footnote {\CONTEXT\
+never assumed this and encourages users to use the quotation macros. Those \type
+{``quotes''} look horrible in a source anyway.} They are not really ligatures but
+abuse the ligature mechanism to achieve a similar effect. The last four lines are
+the most interesting: these are ligatures that (probably) no \TEX\ user ever uses
+or encounters. They are again something from the past. Also, changes are low that
+you mistakenly enter these sequences and the follow up Latin Modern fonts don't
+have them anyway.
+
+Actually, if you look at the \METAFONT and \METAPOST\ sources you can find
+lines like these (here we took from \type {mp.w} in the \LUATEX\ repository):
+
+\starttyping[style=\ttx]
+@ @<Put each...@>=
+mp_primitive (mp, "=:", mp_lig_kern_token, 0);
+@:=:_}{\.{=:} primitive@>;
+mp_primitive (mp, "=:|", mp_lig_kern_token, 1);
+@:=:/_}{\.{=:\char'174} primitive@>;
+mp_primitive (mp, "=:|>", mp_lig_kern_token, 5);
+@:=:/>_}{\.{=:\char'174>} primitive@>;
+mp_primitive (mp, "|=:", mp_lig_kern_token, 2);
+@:=:/_}{\.{\char'174=:} primitive@>;
+mp_primitive (mp, "|=:>", mp_lig_kern_token, 6);
+@:=:/>_}{\.{\char'174=:>} primitive@>;
+mp_primitive (mp, "|=:|", mp_lig_kern_token, 3);
+@:=:/_}{\.{\char'174=:\char'174} primitive@>;
+mp_primitive (mp, "|=:|>", mp_lig_kern_token, 7);
+@:=:/>_}{\.{\char'174=:\char'174>} primitive@>;
+mp_primitive (mp, "|=:|>>", mp_lig_kern_token, 11);
+@:=:/>_}{\.{\char'174=:\char'174>>} primitive@>;
+\stoptyping
+
+I won't explain what happens there (as I would have to reread the relevant
+sections of \TEX\ The Program) but the magic is in the special sequences: \typ
+{=: =:| =:|> |=: |=:> |=:| |=:|> |=:|>>}. Similar sequences are used in some font
+related files. I bet that most \METAPOST\ users never entered these as they
+relate to defining ligatures for fonts. Most users know that combining a \type
+{f} and \type {i} gives a \type {fi} but there are other ways to combine too. One
+can praise today's capabilities of \OPENTYPE\ ligature building but \TEX\ was not
+stupid either! But these options were never really used and this treasure will
+stay hidden. Actually, to come back to a previous remark about abusing the
+ligature mechanism: \OPENTYPE\ fonts are just as sloppy as \TEX\ with the quotes:
+there a ligature is just a name for a multiple|-|to|-|one mapping which is not
+always the same as a ligature.
+
+But there are even more surprises with fonts. When Alan Braslau and I redid the
+bibliography subsystem of \CONTEXT\ with help from \LUA, I wrote a converter in
+that language. I actually did that the way I normally do: look at a file (in this
+case a \BIBTEX\ file) and write a parser from scratch. However, at some point we
+wondered how exactly strings got concatenated so I decided to locate the source
+and look at it there. When I scrolled down I noticed a peculiar section:
+
+\starttyping[style=\ttx]
+@^character set dependencies@>
+@^system dependencies@>
+Now we initialize the system-dependent |char_width| array, for which
+|space| is the only |white_space| character given a nonzero printing
+width. The widths here are taken from Stanford's June~'87
+$cmr10$~font and represent hundredths of a point (rounded), but since
+they're used only for relative comparisons, the units have no meaning.
+
+@d ss_width = 500 {character |@'31|'s width in the $cmr10$ font}
+@d ae_width = 722 {character |@'32|'s width in the $cmr10$ font}
+@d oe_width = 778 {character |@'33|'s width in the $cmr10$ font}
+@d upper_ae_width = 903 {character |@'35|'s width in the $cmr10$ font}
+@d upper_oe_width = 1014 {character |@'36|'s width in the $cmr10$ font}
+
+@<Set initial values of key variables@>=
+for i:=0 to @'177 do char_width[i] := 0;
+@#
+char_width[@'40] := 278;
+char_width[@'41] := 278;
+char_width[@'42] := 500;
+char_width[@'43] := 833;
+char_width[@'44] := 500;
+char_width[@'45] := 833;
+\stoptyping
+
+Do you see what happens here? There are hard coded font metrics in there! As far
+as I can tell, these are used in order to guess the width of the margin for
+references. Of course that won't work well in practice, simply because fonts
+differ. But given that the majority of documents that need references are using
+Computer Modern fonts, it actually might work well, especially with Plain \TEX\
+because that is also hardwired for 10pt fonts. Personally I'd go for a multipass
+analysis (or maybe would have had \BIBTEX\ produce a list of those labels for the
+purpose of analysis but for sure at that time any extra pass was costly in terms
+of performance). That code stays around of course. It makes for some nice
+deduction by historians in the future.
+
+I bet that one can also find weird or unexpected code in \CONTEXT, and definitely
+on the machines of \TEX\ users all around the world. For instance, now that most
+people use \UTF8\ all those encoding related hacks have become history. On the
+other hand, as history tends to cycle, bitmap symbolic fonts suddenly can look
+modern in a time when emoji are often bitmaps. We should guard our treasures.
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-unicode.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-unicode.tex
index 06ec019854b..397a5a2a2c1 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-unicode.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-unicode.tex
@@ -1550,20 +1550,32 @@ the math in his writing doesn't automatically translate in all \TEX ies doing th
same. I don't claim that \CONTEXT\ is doing better but I do hope that its users
keep going for the best outcome.
+One final note. In \CONTEXT\ we always tried to keep up with developments and
+\UNICODE\ input as well as using \OPENTYPE\ math fonts are part of that. However,
+because we're not part of the \quote {gremia of \TEX\ math and related coding} it
+hardly matters what our opinions are with respect to these issues. The best we
+can do is adapt to whatever shows up, it being bad or good. It is however kind of
+funny to see (by now rusty) problems that have been noticed already long ago
+being presented as kind of new. Hopefully staying ahead and|/|or adapting with
+specific solutions doesn't'backfire to hard on the \CONTEXT\ users. If so, we're
+sorry for that. As long as they can render their documents well, it doesn't
+matter that much anyway. After all, we can always just blame \quote {the others
+involved}.
+
\stopsection
\startsection[title=Resources]
\starttyping
-[1] https://en.wikipedia.org/wiki/Slash_(punctuation)
-[2] http://www.unicode.org/reports/tr25
-[3] https://www.w3.org/TR/MathML3
-[4] https://www.unicode.org/Public/math/revision-15/MathClass-15.txt
-[5] https://en.wikipedia.org/wiki/Vertical_bar
-[6] https://en.wikipedia.org/wiki/Dash
-[7] https://en.wikipedia.org/wiki/Commercial_minus_sign
-[8] https://en.wikipedia.org/wiki/Division_sign
-[9] https://en.wikipedia.org/wiki/Bullet_(typography)
+[1] en.wikipedia.org/wiki/Slash_(punctuation)
+[2] www.unicode.org/reports/tr25
+[3] www.w3.org/TR/MathML3
+[4] www.unicode.org/Public/math/revision-15/MathClass-15.txt
+[5] en.wikipedia.org/wiki/Vertical_bar
+[6] en.wikipedia.org/wiki/Dash
+[7] en.wikipedia.org/wiki/Commercial_minus_sign
+[8] en.wikipedia.org/wiki/Division_sign
+[9] en.wikipedia.org/wiki/Bullet_(typography)
\stoptyping
\stopsection
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings.tex b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings.tex
index 2d0e7c09499..84431317935 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings.tex
@@ -21,15 +21,27 @@
\component musings-names
\component musings-plain
\component musings-toocomplex
- % \component musings-manuals
+ \component musings-manuals
\component musings-performance
- % \component musings-history
- % \component musings-treasures
- % \component musings-whytex-again
+ \component musings-history
+ \component musings-treasures
+ % \component musings-whytex-again % maybe
\component musings-dontusetex
\component musings-speed
+ \component musings-unicode
\component musings-texlive
\component musings-hownotto
+ % \component musings-security % maybe
+ % \component musings-usage % maybe
+ % \component musings-sideeffects % article
+ % \component musings-perfection % source included as teaser
+ \component musings-assumptions
+ % \component musings-green % unfinished
+ % \component musings-cheats
+ % \component musings-units % article
+ % \component musings-kerns % probably article
+ \component musings-deserved % probably article
\stopbodymatter
\stopproduct
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-accuracy.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-accuracy.tex
new file mode 100644
index 00000000000..16e89b049c0
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-accuracy.tex
@@ -0,0 +1,198 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\startcomponent ontarget-accuracy
+
+\environment ontarget-style
+
+\startchapter[title={Accuracy}]
+
+One of the virtues of \TEX\ is that it can produce the same output over a long
+period. The original engine only uses integers and although dimensions have
+fractions but these are just a way to present then to the user because internally
+they are scaled points.
+
+\starttabulate[|l|l|]
+\FL
+\NC \type{\dimexpr .4999pt : 2 \relax} \NC
+ \the\dimexpr .4999pt : 2 \relax
+\NC \NR
+\NC \type{\dimexpr .4999pt / 2 \relax} \NC
+ \the\dimexpr .4999pt / 2 \relax
+\NC \NR
+\ML
+\NC \type{\scratchdimen.4999pt \divide \scratchdimen 2 \the\scratchdimen} \NC
+ \scratchdimen.4999pt \divide \scratchdimen 2 \the\scratchdimen
+\NC \NR
+\NC \type{\scratchdimen.4999pt \edivide\scratchdimen 2 \the\scratchdimen} \NC
+ \scratchdimen.4999pt \edivide\scratchdimen 2 \the\scratchdimen
+\NC \NR
+\ML
+\NC \type{\scratchdimen4999pt \divide\scratchdimen 2 \the\scratchdimen} \NC
+ \scratchdimen4999pt \divide\scratchdimen 2 \the\scratchdimen
+\NC \NR
+\NC \type{\scratchdimen4999pt \edivide\scratchdimen 2 \the\scratchdimen} \NC
+ \scratchdimen4999pt \edivide\scratchdimen 2 \the\scratchdimen
+\NC \NR
+\NC \type{\scratchdimen4999pt \rdivide\scratchdimen 2 \the\scratchdimen} \NC
+ \scratchdimen4999pt \rdivide\scratchdimen 2 \the\scratchdimen
+\NC \NR
+\ML
+\NC \type{\numexpr 1001 : 2 \relax} \NC
+ \the\numexpr 1001 : 2 \relax
+\NC \NR
+\NC \type{\numexpr 1001 / 2 \relax} \NC
+ \the\numexpr 1001 / 2 \relax
+\NC \NR
+\ML
+\NC \type{\scratchcounter1001 \divide \scratchcounter 2 \the\scratchcounter} \NC
+ \scratchcounter1001 \divide \scratchcounter 2 \the\scratchcounter
+\NC \NR
+\NC \type{\scratchcounter1001 \edivide\scratchcounter 2 \the\scratchcounter} \NC
+ \scratchcounter1001 \edivide\scratchcounter 2 \the\scratchcounter
+\NC \NR
+\LL
+\stoptabulate
+
+The above table shows what happens when we divide an odd integer or for that
+matter odd fraction. Note the incompatibility between \type {\numexpr} and \type
+{\dimexpr} on the one hand and \type {\divide} on the other. This is why in
+\LUAMETATEX\ we have the \type {:} variant that does the same integer divide (no
+rounding) as \type {\divide} does, and why we have \type {\edivide} that divides
+like an expression using the \type {/}. The \type {\rdivide} only makes sense for
+dimensions and rounds the result.
+
+As soon as one start calculating or comparing accumulated values one can run into
+the values being a few scaled points off. This means that when one tests against
+a criterium it might be that some range comparison is better. The most likely
+place for that to happen is in the output routine and when special constructs
+like floats, tables and images come into play. Just like not every number can be
+represented in a float (double), we saw that dividing an odd integer can give
+some unexpected rounding as part of the integer is considered a fraction. So, in
+practice, even when the calculations are the same, there is a certain
+unpredictable outcome from the user perspective: \quotation {Why does it fit here
+and not there?} Well, we can be a few scaled points off due to some not entirely
+round|-|trip calculation.
+
+When \TEX\ showed up it came with fonts and in those times once a font was
+released it was unlikely to change. But today fonts do change. And changes means
+that a document can render differently after an update. Of course this is an
+argument for keeping a font in the \TEX\ tree but even then updating is kind of
+normal. Take math: the fact that fonts often have issues makes that we need to
+tweak them and some tweaks only get added when we run into some issue. If that
+issue has been there for a while we are incompatible.
+
+Hyphenation patterns are another source of breaking compatibility but normally
+they change little. And here one can also assume that the user want words to be
+hyphenated properly. Even with such fundamental changes as a syllable being able
+to move to the next line, it is often unlikely that the paragraphs gets less or
+more lines. I bet that users are more worried about the impact on vertical
+rendering that has consequences for page breaks that for lines coming out
+differently (hopefully better).
+
+So, what are other potential areas in addition to slight differences due to
+division, fonts and patterns? We now enter the world of \LUAMETATEX\ and
+\CONTEXT. As soon as one starts to use \LUA\ code, doubles show up. It means that
+we can do calculation with little loss because a double can safely hold the
+maximum dimension (in scaled point). However, mixing 64 bit doubles at the \LUA\
+end with 32 bit integers in the engine can have side effects. As soon as set some
+property at the \TEX\ end using \LUA\ rounding takes place. Of course we can do
+all calculations like \TEX\ does, but that would have too much of an impact on
+performance.
+
+So, going back and forth between \TEX\ and \LUA\ can introduce some inaccuracies
+creeping in but as long as it is consistent, there is no real issue. It mostly
+involves fonts and especially the dimensions of characters: the width, height and
+depth but when one uses the xheight as relative measure there is also some
+influence on for instance interline spacing, offsets and such.
+
+So how can fonts make a difference? In \CONTEXT\ there are two ways to use fonts:
+normal mode and compact mode. In normal mode every size is an instance, where the
+dimension properties of characters are scaled. In compact mode we use one size
+and delegate scaling to the engine which means that we end up with the (usual)
+1000 being scale 1 kind of calculations. In the end a font with design size of
+10bp (most fonts) scaled to 12pt normal is not behaving the same as a 10pt setup
+where a 12pt size is scaled on demand. First there is the scaling from 10bp
+loaded font to the 10pt used font that gets passed to \TEX. Here we have to deal
+with history: defining a font in pt points is quite normal. Then applying a 1200
+scale (later divided by 1000) in the engine again involves some rounding to
+integers because that is what is used internally. I will come back to this later.
+
+The main conclusion to draw is that normal mode and compact mode come close but
+give different results. We can come closer when we a more accurate normal mode.
+In order to limit the number of font instances we normally limit the number of
+digits (also in compact mode but there accuracy comes a little cost). There is a
+pitfall here: While \TEX\ can happily work with any resolution, the backend has
+to make sure that embedded fonts get scaled right and that (in the case of \PDF)
+we compensate for drift in the page stream, because there character widths
+determine the advance and these are in (often rounded) bp (big postscript
+points). Especially when we enable font expansion drift prevention comes with a
+price as there we are dealing with real small difference in dimensions.
+
+As an experiment I played with clipping measures in the engine which boils down
+to rounding the last digit but that didn't work out well. For simple text we can
+get normal and compact mode identical but kick in some math (many parameters
+involved), font expansion and|/|or protrusion, additional inter|-|character
+kerning and so on, and one never get the same output. Keep in mind that we are
+not talking visual differences here, although there can be cases. More think of
+due to a slightly different vertical spacing triggering a different page break,
+for instance when footnotes are involved. In \CONTEXT\ the line height (and
+therefore derived parameters) is defined in terms of the xheight so even a few
+scaled points off makes a difference.
+
+At the user level, currently compact mode is enabled with:
+
+\starttyping
+\enableexperiments[fonts.compact]
+\stoptyping
+
+It works quite okay already for years (writing end 2023) in most scenarios but
+there might be cases where existing code still needs to be adapted, which is no
+big deal. The additional overhead is compensated by loading less font instances
+and a smaller output file. In some cases documents actually process faster and it
+definitely pays of for large fonts (\CJK) and demanding mix size feature
+processing.
+
+A more accurate normal mode is set by:
+
+\starttyping
+\enableexperiments[fonts.accurate]
+\stoptyping
+
+but it doesn't bring much. It was introduced in order for Mikael Sundqvist and me
+to compare and check math tweaks, especially those that depend on precise
+combinations of glyphs. We temporary had some additional control in the engine
+but after experiments and comparing variants the decision was made to remove that
+feature.
+
+We ran experiments with large documents where different versions were overlaid
+and depending on scenarios indeed there can be differences, but when there are
+chapters starting on new pages and when vertical spacing has stretch, there are
+not that many differences. When you compare the so called \type {tuc} files you
+might notice small difference is position tracking but these values are seldom
+used in a way that influences the rendering of text, line and page breaks.
+
+\def\RatioBpPt{( \number \dimexpr 10bp \relax / \number \dimexpr 10pt \relax ) }
+
+To come back to the bp vs pt issue. Among the options considered are moving the
+character and font properties from integers to doubles, but that would impact the
+memory footprint quite a bit. Another idea is that compact mode goes 10bp instead
+of 10pt but that would not help. One bp is \number \dimexpr 10bp \relax \space
+scaled points and one pt is \number \dimexpr 10pt \relax \space sp. The ratio
+between them is \cldcontext { \RatioBpPt }, so a \TEX\ scale 1200 effectively
+becomes \formatted { "\letterpercent .3N", 1200 * \RatioBpPt }, and assuming
+rounding to an integer we then get \cldcontext { math.round ( 1200 * \RatioBpPt
+) }. So in the end we get a less fortunate number instead of 1200 and it's not
+even accurate. Therefore this option was also rejected. For the record: an
+intermediate approach would have been to cheat: use an internal multiplier (the
+shown ratio) and although it is not hard to support, it also means that at the
+\LUA\ end we always need to take this into account, so again a no|-|go.
+
+In the end the only outcome of this bit of \quote {research} has been that we can
+have accurate normal font handling (which is not that useful) and have two
+additional divide related primitives that might be useful and add some
+consistency (and these might actually get used).
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-active.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-active.tex
new file mode 100644
index 00000000000..0f9e418da05
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-active.tex
@@ -0,0 +1,252 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\startcomponent ontarget-active
+
+\environment ontarget-style
+
+\usemodule[system-tokens]
+
+\startchapter[title={Active characters}]
+
+Each character in \TEX\ has a so called category code. Most are of category
+\quote {letter} or \quote {other character} but some have a special meaning, like
+\quote {superscript} or \quote {subscript} or \quote {math shift}. Of course the
+backslash is special too and it has the \quote {escape} category.
+
+A single character can also be a command in which case it has category \quote
+{active}. In \CONTEXT\ the \type {|} is an example of that. It grabs an argument
+delimited by yet another such (active) bar and handles that argument as compound
+character.
+
+From the perspective of \CONTEXT\ we have a couple of challenges with respect to
+active characters.
+
+\startitemize
+\startitem
+ We want to limit the number of special symbols so we only really have to deal with the
+ active bar and tilde. Both have a history starting with \MKII.
+\stopitem
+\startitem
+ There are cases where we don't want them to be not active, most noticeably in
+ math and verbatim. This means that we either have to make a sure that they
+ are not active bit in nested exceptions, for instance when we flush a page
+ halfway verbatim, made active again.
+\stopitem
+\startitem
+ In text we always hade catcode regimes to deal with this (which is actually
+ why in \LUATEX\ efficient catcode tables were one of the first native
+ features to implement. This involves some namespace management.
+\stopitem
+\startitem
+ In math we have to fall back on a different meaning which adds another
+ (meaning) axis alongside catcode regimes: in math we use the same catcode
+ regime as in text so we have a mode dependent meaning on top of the catcode
+ regime specific one.
+\stopitem
+\startitem
+ In math we have this special active class|/|character definition value \type
+ {"8000} that makes characters active in math only. We use(d) that for permitting
+ regular hat and underscore characters in text mode but let them act as
+ superscript and subscript triggers in math mode.
+\stopitem
+\startitem
+ Active characters travel in a special way trough the system: they are
+ actually stored as macro calls in token lists en macro bodies. This normally
+ goes unnoticed (and is not that different from other catcodes being frozen in
+ macros).
+\stopitem
+\stopitemize
+
+So far we could always comfortably implement whatever we wanted but sometimes the
+code was not that pretty. Because part of the \LUAMETATEX\ project is to make
+code cleaner, I started wondering if we could come up with a better mechanism for
+dealing with active characters especially in math. Among the other reasons were:
+less tracing clutter, a bit more natural approach, and less intercepts for
+special cases. Of course we have to be compatible. Some first experiments were
+promising but as usual it took a while to identify all the cases we have to deal
+with. At moments I wondered if I should go forward but as I stepwise adapted the
+\CONTEXT\ code to the experiment there was no way back. I did however reject
+experiments that out active characters in the catcode table namespaces.
+
+In \LUATEX\ (and its predecessors) internally active characters are stored as a
+reference to a control sequence, although a \type {\show} or trace will report
+the character as \quote {name}. For example:
+
+\startbuffer
+\catcode `!=\activecatcode
+\def !{whatever} % we also have \letcharcode
+\def\foo{x!x}
+\stopbuffer
+
+\typebuffer
+
+is stored as (cs, cmd, chr):
+
+\start
+\getbuffer
+\luatokentable\foo
+\stop
+
+However, when we want some more hybrid approach, a text versus math mix, we need
+to postpone resolving into a control sequence. Examples are macro bodies and
+token registers. When we flag a character (with \type {amcode}) as being of a
+different catcode than active in math mode, we get the following:
+
+\startbuffer
+\amcode`! \othercatcode
+\catcode `!=\activecatcode
+\def !{whatever}
+\def\foo{x!x}
+\stopbuffer
+\typebuffer
+
+\start
+\getbuffer
+\luatokentable\foo
+\stop
+
+The difference is that here we get the active character in the body of the macro.
+Interesting is that this is not something that parser is prepared for so the main
+loop has now to catch active characters. This is no big deal but also not
+something to neglect. The same is true for serialization of tokens.
+
+Other situations when we need to be clever is for instance when we try to enter
+math mode. In math mode we want the (in text) active character as math character
+and a convenient test is checking the mode. However, when we see \type {$} we are
+not yet in math mode and as \TEX\ looks for a potential next \type {$} we grab a
+active character it should not resolve in a reference to an command. The reason
+for that is that when \TEX\ pushes back the token (because it doesn't see a \type
+{$}) we need it to be an active character and not a control sequence. If it were
+a control sequence we would see it as such in math mode which is not what we
+intended. It is one of these cases where \TEX\ is not roundtrip. Similar cases
+occur when \TEX\ looks ahead for (what makes a) number and doesn't see one which
+then results in a push back. Actually, there are many look ahead and push back
+moments in the source.
+
+\startbuffer
+text: \def\foo{x|!|x}
+
+\meaningasis\foo
+
+\luatokentable\foo
+
+$x\foo x$ \foo
+\stopbuffer
+
+\typebuffer \start\getbuffer\stop
+
+\startbuffer
+math: $\gdef\oof{x|!|x}$
+
+\meaningasis\oof
+
+\luatokentable\oof
+
+$x\oof x$ \oof
+\stopbuffer
+
+\typebuffer \start\getbuffer\stop
+
+\startbuffer
+toks: \scratchtoks{x|!|x}
+
+\detokenize\expandafter{\the\scratchtoks}
+
+\luatokentable\scratchtoks
+
+$x\the\scratchtoks x$ \the\scratchtoks
+\stopbuffer
+
+\typebuffer \start\getbuffer\stop
+
+A good test case for \CONTEXT\ is:
+
+\startbuffer
+\def\foo{x|!|x||x}
+
+ x|!|x||x + \foo
+$x|!|x||x + \foo$
+\stopbuffer
+
+\typebuffer
+
+Here we expect bars in math mode but the compound mechanism applied in text mode:
+
+\startlines\getbuffer\stoplines
+
+So the bottom line is this:
+
+\startitemize
+\startitem
+ Active characters should behave as expected, which means that they get
+ replaced by references to commands.
+\stopitem
+\startitem
+ When the \type {\amcode} is set, this signal the engine to delay that
+ replacement and retain the active character.
+\stopitem
+\startitem
+ When the moment is there the engine either expands it as command (text mode)
+ or injects the alternative meaning based on the catcode. There we support
+ letters, other characters, super- and subscripts and alignment codes. The
+ rest we simply ignore (for now).
+\stopitem
+\stopitemize
+
+Of course you can abuse this mechanism and also retain the character's active
+property in text mode by simply setting the \type {\amcode}. We'll see how that
+works out. Actually this mechanism was provided in the first place to get around
+the \type {"8000} limitations! So here is another cheat:
+
+\starttyping
+\catcode `^ \othercatcode % so a ^ is just that
+\amcode `^ \superscriptcatcode % but a ^ in math signals a superscript
+\stoptyping
+
+So, the \type {a} in \type {\amcode} stands for both \quote {active} and \quote
+{alternative}. As mentioned, because we distinguish between math and text mode we
+no longer need to adapt the meaning of active commands: think of using \type
+{\mathtext} in a formula where we leave math mode and then need to use the text
+meaning of the bar, just as outside the formula.
+
+In the end, because we only have a few active characters and no user ever
+demanded name spaces that mechanism was declared obsolete. There is no need to
+keep code around that is not really used any more.
+
+% Although this mechanism works okay, there is a pitfall. When you define a macro, and
+% \type {\amcode} is set, the active character is stored as such. That means that doing
+% something like this is likely to fail:
+%
+% \starttyping
+% \def\whatever{\let~\space}
+% \stoptyping
+%
+% when the tilde is active as well as has a \type {\amcode} set. However,
+%
+% \starttyping
+% \def\whatever{\letcharcode\tildeasciicode\space}
+% \stoptyping
+%
+% will work just fine.
+
+Internally an active character is stored in the hash that also stores regular
+control sequences. The character becomes an \UTF\ string prefixed by the \UTF\
+value of \type {0xFFFF} which doesn't exist in \UNICODE. The \type {\csactive}
+primitive is a variant on \type {\csstring} that returns this hash. Its companion
+\type {\expandactive} (a variant on \type {\expand}) can be used to inject the
+related control sequence. If \type {\csactive} is not followed by an active
+character it expands to just the prefix, as does \type {\Uchar"FFFF} but a bit of
+abstraction makes sense.
+
+% control sequence: xxxx
+% 271731 13 126 active char
+% control sequence: xxxx
+% 271732 135 0 protected call ~
+% control sequence: xxxx
+% 271734 12 65535 other char ï¿¿ (U+0FFFF)
+% 408124 135 0 protected call ~
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-bars.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-bars.tex
new file mode 100644
index 00000000000..21a6eb6c099
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-bars.tex
@@ -0,0 +1,204 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\startcomponent ontarget-bars
+
+\usebodyfont[modern]
+\usebodyfont[modern-nt]
+
+\environment ontarget-style
+
+\startchapter[title={Between bars}]
+
+\startsubject[title=Inconsistencies]
+
+The bar in math can a real pain. There are several reasons for this, for instance
+there is no proper left, middle and right bar in \UNICODE\ and as a result there
+is more work involved in getting them spaced well. Another possible issue can be
+to make them fit well with other fences. You expect the bars in \im {\left(x
+\middle| y\right)} and \im {\left|x \middle| y\right|} to look similar.
+
+\start \glyphscale2000 \startformula
+ \mathaxisbelow \dorecurse {\nofmathvariants \barasciicode} {
+ \char \getmathvariant #1 \leftbracketasciicode
+ \char \getmathvariant #1 \barasciicode
+ \char \getmathvariant #1 \rightparentasciicode
+ \quad
+ }
+\stopformula \stop
+
+However, math fonts have their surprises:
+
+\start \switchtobodyfont[modern-nt] \glyphscale2000 \startformula
+ \mathaxisbelow \dorecurse {\nofmathvariants \barasciicode} {
+ \char \getmathvariant #1 \leftbracketasciicode
+ \char \getmathvariant #1 \barasciicode
+ \char \getmathvariant #1 \rightparentasciicode
+ \quad
+ }
+\stopformula \stop
+
+In Latin Modern only the first variant is tuned to work together but for larger
+sizes the bars stick out. This is a problem when we want fences to adapt. The
+fact that such side effects probably get unnoticed comes from the fact that macro
+packages assume \type {\bigg} and friends to be used but in \CONTEXT, and
+especially \LMTX, we have various mechanisms for this. One method is based on
+selecting specific variants, in the case of Latin Modern 1, 4, 6 and 7, where in
+in fact 7 is the last one before we switch to extensible fences. One can try to
+use a different selection for brackets and bars when there is no nice match but
+there are no equal height matches.
+
+\startbuffer
+\im {\left| x \right|}
+\im {\left| x^2 \right|}
+\im {\left| x^{1/n} \right|}
+\stopbuffer
+
+\typebuffer
+
+These example formulas can trigger a larger fence:
+
+\startlinecorrection \showglyphs
+\ruledhbox{\scale[width=1tw]{\getbuffer}}
+\stoplinecorrection
+
+In untweaked Latin Modern we get this:
+
+\startlinecorrection \switchtobodyfont[modern-nt] \showglyphs
+\ruledhbox{\scale[width=1tw]{\getbuffer}}
+\stoplinecorrection
+
+The slash in this font is rather high and therefore triggers the larger fence.
+One can configure this with the \typ {\delimiterfactor} and \typ
+{\delimitershortfall} but as you can see values have to relate to the font. In
+\LMTX\ we set them to 1000 and 0pt and use the \LUAMETATEX\ equivalent font
+variables instead, so we can indeed fine tune per font.
+
+To come back to the mismatch in fences, this is dealt with in a tweak: we scale
+the single, double and triple bars to match the brackets:
+
+\start \switchtobodyfont[modern] \startformula
+ \mathaxisbelow \dorecurse {\nofmathvariants \barasciicode} {
+ \char \getmathvariant #1 \leftbracketasciicode
+ \char \getmathvariant #1 \barasciicode
+ \char \getmathvariant #1 \rightparentasciicode
+ \quad
+ }
+\stopformula \stop
+
+Combined with proper settings for the factor (or percentage in \OPENTYPE\ math
+speak) and shortfall, we now get:
+
+\startlinecorrection \switchtobodyfont[modern] \showglyphs
+\ruledhbox{\scale[width=1tw]{\getbuffer}}
+\stoplinecorrection
+
+When we let the upgraded math subsystem evolve we make many examples.
+Unfortunately there is always an exception. For instance, we test a specific
+font, notice something, deal with it, even test all fonts in inline and display
+math and then after months the exception shows up. In this case it was the \im
+{1/n} in a superscript that (only?) in Latin Modern goes over the top. Actually
+we had noticed that bars are often inconsistent so we had a \type {fixbars}
+tweak, However, for Latin Modern we found that the inconsistency between bars and
+other fences needed something more drastic. Of course fixing the font is best but
+we're beyond that stage now: the fonts are basically frozen.
+
+A close inspection of the too large fence which itself results from it being
+larger than expected by design (which we noticed by adding parentheses) itself
+was the result from deciding to configure additional inter|-|atom spacing for
+open and close fences (see below) which then brings us back to the fact that one
+bar serves three purposes. We might actually introduce these three (left, middle
+and right) at some point.
+
+\startbuffer
+\dm {\left| \frac{n^3 - 2n + 1}{n^5 - 3} - 0 \right| < \frac{4}{n^2} }
+\stopbuffer
+
+\startlinecorrection
+\switchtobodyfont[modern]
+\hbox{\scale[width=.45tw]{\getbuffer}\hskip .1tw
+\inherited\setmathspacing\mathordinarycode\mathclosecode\allmathstyles\zeromuskip
+\scale[width=.45tw]{\getbuffer}}
+\stoplinecorrection
+
+\stopsubject
+
+\startsubject[title=Missing shapes]
+
+The tweak discusses in the previous section is a brute force one: we put an
+extensible on the base glyph. Among the arguments for doing this is that we want
+to be able to add consistent double and triple bars. Without mentioning fonts
+explicitly (as some might get fixed after we files bug reports) this is what
+we observed:
+
+\startitemize[packed]
+\startitem
+ There are single bars, double bars and triple bars and each has variants and
+ extensibles. This is okay.
+\stopitem
+\startitem
+ Most are there but the triple bar has no variants and extensibles
+\stopitem
+\startitem
+ We have all three base characters but no variants. The extensible has a
+ different width.
+\stopitem
+\startitem
+ Single, double and triple bars are inconsistent with each other.
+\stopitem
+\startitem
+ Everything is there but widths differ per variant; some match the parenthesis,
+ brackets and braces but not consistently.
+\stopitem
+\startitem
+ The different variant sizes are out of sync with the sizes of parenthesis
+ etc.\ and this makes for inconsistent matches, especially when also the width
+ and positioning differs.
+\stopitem
+\startitem
+ Spacing between and around double and triple bars isn't always consistent.
+\stopitem
+\stopitemize
+
+These observations lead us to the conclusion that there is no single tweak that
+can fix this. Adapting the \quote {addbars} tweak to deal with all this made for
+too many alternatives in checks and fixes to feel comfortable with. This is why
+we decided to come up with companion fonts that provide the missing double and
+triple variants and extensibles consistent with the single ones, fix spacing in
+double and triple ones, fix inconsistent widths of bars, etc. Minor details like
+bad positioning are already handled well do we can keep the \quote {design} as it
+is.
+
+\usebodyfont[pagella]
+
+\start
+\switchtobodyfont[pagella,15pt]
+\dm{
+ \dorecurse {\nofmathvariants "28} {
+ \char \getmathvariant #1 "5B
+ \char \getmathvariant #1 "7B
+ \char \getmathvariant #1 "28
+ \char \getmathvariant #1 "7C
+ \char \getmathvariant #1 "29
+ \char \getmathvariant #1 "7D
+ \char \getmathvariant #1 "5D \quad }
+}
+
+\dm{
+ \dorecurse {\nofmathvariants "7C} {
+ \char \getmathvariant #1 "7C \enspace
+ \char \getmathvariant #1 "2016 \enspace
+ \char \getmathvariant #1 "2980 \quad }
+}
+\stop
+
+\stopsubject
+
+\startsubject[title=Different sizes]
+
+middle
+
+\stopsubject
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-constants.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-constants.tex
new file mode 100644
index 00000000000..958e78dc2bc
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-constants.tex
@@ -0,0 +1,220 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\startcomponent ontarget-constants
+
+\environment ontarget-style
+
+\usemodule[system-tokens]
+
+\startchapter[title={Constants}]
+
+Strings don't really fit into the concept of \TEX. There everything we input and
+store is tokens and nodes, so when you define a macro like
+
+\startbuffer
+\def\foo{foo}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+you don't store a string but a tokenlist with three tokens:
+
+\luatokentable\foo
+
+We have three single byte characters but end up with 32 bytes memory used because
+we have a linked list with a housekeeping initial token; such a token has a value
+(operator & operand) as well as a pointer to a next token. This is quite ok
+because whenever we need that macro the body has to be interpreted and it already
+being tokenized is what makes \TEX\ fly.
+
+There are occasions where the expansion of a list that itself can contain
+references to macros produces a new list in which case copies are being made.
+Take this:
+
+\startbuffer
+\def\oof{foo}
+\def\foo{foo \oof}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\luatokentable\foo
+
+When \type {\foo} is expanded, the macro body is pushed onto the input stack and
+traversed and when \type {\oof} is seen, that one gets pushed and processed. No
+copy is needed. Now take this:
+
+\startbuffer
+\def\oof{foo}
+\edef\foo{foo \oof}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\luatokentable\foo
+
+Here \type {\foo} gets the expanded result but again \type {\oof} got pushed onto
+the stack. This doesn't involved copying either but there is still the pushing
+and popping input overhead. So when does copying occur? Here is an example:
+
+\startbuffer
+\def\oof{oof}
+\def\ofo{ofo}
+\def\foo{\begincsname \oof:\ofo\endcsname}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\luatokentable\foo
+
+When a csname is checked, the engine needs to construct a string in order to access the
+hash table. Here is what happens:
+
+\startitemize[packed]
+\startitem
+ everything upto the \type {\endcsname} is collected
+\stopitem
+\startitem
+ in the process macros are expanded (with pushing and popping input) and the
+ expanded tokens are appended to the result
+\stopitem
+\startitem
+ when we're okay that list get converted to a string
+\stopitem
+\startitem
+ that string is used as lookup into the hash
+\stopitem
+\stopitemize
+
+Normally we're okay but when there is some unexpected unexpandable token (an
+assignment, node generator, protected macro, etc.) the collection stops and the
+list so far is recycled. This process is quite efficient, as is everything \TEX,
+but given that going from token list to string involved some \UTF8 juggling too
+there definitely is some overhead.
+
+In \CONTEXT\ we use csname checking and usage quite a lot. The first line is the
+traditional way. It has the disadvantage that it creates an hash entry with alias
+\type {\relax} if there is no such name. That is why \ETEX\ came up with the test
+as in the second line. In \LUATEX\ we introduced \type {\lastnamedcs} so that we
+don't have to construct the mentioned) token list again which saves time. The
+fourth line is similar to the first line but doesn't create a new command.
+
+\starttyping
+\csname \namespace\key\endcsname ...
+\ifcsname \namespace\key\endcsname \csname \namespace\key\endcsname ... \fi
+\ifcsname \namespace\key\endcsname \lastnamedcs ... \fi
+\begincsname \namespace\key\endcsname
+\stoptyping
+
+One of the things all versions of \CONTEXT\ have in common (right from the start)
+is that we use this namespace model consistently. In \MKIV\ we changed the
+subsystem that deals with this: it's more flexible and uses less memory but it
+also has way more overhead. But on the average performance is about the same so
+users didn't notice that.
+
+There is however a trick to speed this up a bit. In the 360 page \LUAMETATEX\
+manual we expand macros like \type {\namespace} and \type {\key} 4.3 million
+times (beginning of June 2023). Because Mikael Sundqvist and I are in the middle
+of some math magic, we also checked his 300 page math book, and that also does it
+4.2 million times (the gain was about 0.5 seconds). The upcoming math manual has
+some 1.2 million. How come that we have so many expansions? First of all we use
+abstraction when possible and that means that there's plenty of checking of
+options and some constructs fall back on parent classes (sometimes more that two
+times up the parent chain). Also, we often have three macros to expand:
+
+\starttyping
+\ifcsname\namespace\currentinstance\key\endcsname
+\stoptyping
+
+But these have an important property: their body is basically a string. Nothing
+in there needs expansion and if it does, it's an indication of rubish that
+doesn't contribute for a valid csname anyway. Once we know that we can improve
+performance:
+
+\startbuffer
+\cdef\oof{oof}
+\cdef\ofo{ofo}
+\def\foo{\begincsname \oof:\ofo\endcsname}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+So, \type {\cdef} (or \type {\constant \edef} flags the macro as being a constant
+that doesn't require expansion. For the record, when you define that macro having
+arguments it just becomes an \type {\edef}.
+
+\luatokentable\foo
+
+Here we define the two macros as constant ones which in practice means that they
+are just macros but also indicates that in some scenarios we can directly use
+their body. Now when in this csname construction we do this instead:
+
+\startitemize[packed]
+\startitem
+ everything upto the \type {\endcsname} is collected
+\stopitem
+\startitem
+ in the process macros are expanded (with pushing and popping input) but when
+ we have a constant we add reference token when there is more than one body
+ token, otherwise the expanded tokens are appended to the result
+\stopitem
+\startitem
+ when we're okay that list get converted to a string and in that stage we just
+ convert the referenced body of the constant
+\stopitem
+\startitem
+ that string is used as lookup into the hash
+\stopitem
+\stopitemize
+
+So, instead of immediately injecting an expanded body of a macro that needs no
+expansion we inject a reference and use that later on for the conversion into
+characters. On the 4242938 times in \LUAMETATEX\ (at the time of writing this) this
+trick gives the following results.
+
+\starttyping
+\edef\foo{xxxx} \begincsname\foo\endcsname 0.37
+\cdef\foo{xxxx} \begincsname\foo\endcsname 0.28
+\edef\foo{xxxx} \ifcsname\foo\endcsname\fi 0.53
+\cdef\foo{xxxx} \ifcsname\foo\endcsname\fi 0.35
+\stoptyping
+
+And here for an existing command (\type {\relax}):
+
+\starttyping
+\edef\foo{relax} \begincsname\foo\endcsname 0.55
+\cdef\foo{relax} \begincsname\foo\endcsname 0.36
+\edef\foo{relax} \ifcsname\foo\endcsname\fi 0.62
+\cdef\foo{relax} \ifcsname\foo\endcsname\fi 0.36
+\stoptyping
+
+When I used that trick in for instance some font switching macros it also had
+some gain. For instance 200000 times \type {\it} went from 0.60 down to 0.54
+seconds but it is unlikely that in a document one does that many font switches.
+\footnote {There are a few more places where constants can gain a little but
+those don't add up much.}
+
+In practice other operations play a role, so here we might also benefit from the
+data being in the \CPU\ cache but on the manual I gained a decent .2 seconds. One
+can question if on a 8.5 second run this is worth the trouble. However, in this
+particular manual we spend 3.5 seconds on font processing, some 1.5 seconds on
+the backend and have a unique \METAPOST\ graphics on every page. We spend more
+time in \LUA\ than in \TEX ! On 4 seconds \TEX, these .2 seconds is some 2.5
+gain, and it might actually be even more percent wise.
+
+In case one wonders why I spend time on this, one reason is that the last decade
+I was not that impressed by performance gains of a single core and \TEX\ is a
+single core process. I also can't afford the latest greatest laptops and
+definitely don't want to contribute more e-waste. Also, with \TEX\ and friends
+running on virtual machines and competing for resources (memory, \CPU\ and disk
+or network drives) any gain is good gain. Of course it is also fun to improve
+\LUAMETATEX\ and this string-like property has always bothered me. \footnote {I
+did some experiment with a native string register but that made no sense because
+then tokenization in other places takes a toll. With the mentioned constants we
+don't pay that price.}
+
+\stopchapter
+
+\stopcomponent
+
+% timestamp: Peter Gabriel Live 2023 Amsterdam
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-envelopes.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-envelopes.tex
new file mode 100644
index 00000000000..07d2fe168f6
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-envelopes.tex
@@ -0,0 +1,914 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\startcomponent ontarget-envelopes
+
+\environment ontarget-style
+
+\startchapter[title={Pushing the envelope}]
+
+Here I describe the results of some exploration and experiments by Mikael
+Sundqvist and me. We got sidetracked from intersections, arcs and drawing
+functions when we noticed some artifacts with envelopes. But what are envelopes
+actually? Let us start with a simple path:
+
+\startbuffer[testpath]
+\startMPinclusions
+ path TestPath ; TestPath := fullcircle xyscaled (10cm,1cm)
+\stopMPinclusions
+\stopbuffer
+
+\startbuffer[a]
+\startMPcode
+ draw TestPath withpen pencircle scaled 2mm withcolor darkred ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[b]
+\startMPcode
+ fill TestPath withpen pencircle scaled 2mm withcolor darkred ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[c]
+\startMPcode
+ draw TestPath withpen pensquare scaled 2mm withcolor darkblue ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[d]
+\startMPcode
+ fill TestPath withpen pensquare scaled 2mm withcolor darkblue ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[e]
+\startMPcode
+ fill TestPath withpen pensquare scaled 2mm withcolor darkgreen
+ withtransparency (1,.5) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[testpath]
+
+When we draw this with a circular pen we get this:
+
+\typebuffer[a] \startlinecorrection \getbuffer[testpath,a] \stoplinecorrection
+
+Filling gives:
+
+\typebuffer[b] \startlinecorrection \getbuffer[testpath,b] \stoplinecorrection
+
+When a \type {pencircle} is used \METAPOST\ delegates the work to the backend
+because \POSTSCRIPT\ has a circular pen, otherwise it has to calculate the
+to|-|be|-|filled shape itself. The backend has to do some path juggling in the
+case of \PDF\ because there a pen transform is different from \POSTSCRIPT.
+
+\typebuffer[c] \startlinecorrection \getbuffer[testpath,c] \stoplinecorrection
+
+Here we draw the shape with a square pen while filling gives:
+
+\typebuffer[d] \startlinecorrection \getbuffer[testpath,d] \stoplinecorrection
+
+In most cases this works out well but there are some hidden issues. These get
+exposed when we use a transparency:
+
+\typebuffer[e] \startlinecorrection \getbuffer[testpath,e] \stoplinecorrection
+
+It are these artifacts that we will explore a little. For that we will render
+quite some graphics. We could show numerous more examples but when you are a
+\CONTEXT\ user you will be able to make plenty yourself by looking at these
+examples.
+
+\startbuffer[e]
+\startMPcode
+ fill fullcircle xyscaled (.8TextWidth,2cm)
+ withpen pensquare scaled 8mm
+ withcolor darkgreen
+ withtransparency (1,.5) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[e] \startlinecorrection \getbuffer[testpath,e] \stoplinecorrection
+
+When we were playing with the \type {envelope} primitive we noticed these
+artifacts and we spent quite some time looking at the code to see where it comes
+from and if we could prevent this. It was then that we realized that the fill
+actually also uses these envelopes but that it gets delayed till the shapes are
+flushed to the backend. That meant that we could use fills with transparencies
+as simple test cases.
+
+The first thing to get rid of is the weird blob at the right end of the fill in
+this example. Not really understanding all what went on, we explored all kind of
+shapes and temporarily disabled some of the code in the \METAPOST\ library to see
+where it crept in. We decided that touching the code to get rid of for instance
+rounding issues or potential direction related side effects made no sense. In the
+end the solution was simple:
+
+\startbuffer[e]
+\startMPcode
+ pen p ; p := makepen(unitsquare rotated eps) ;
+ fill fullcircle xyscaled (.8TextWidth,2cm)
+ withpen p scaled 8mm
+ withcolor darkgreen
+ withtransparency (1,.5) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[e] \startlinecorrection \getbuffer[testpath,e] \stoplinecorrection
+
+We show what the \type {envelope} primitive gives us:
+
+\startbuffer[e]
+\startMPcode
+ pen p ; p := makepen(unitsquare rotated eps) ;
+ path e ; e :=
+ envelope (p scaled 8mm)
+ of
+ (fullcircle xyscaled (.8TextWidth,2cm))
+ ;
+ draw e
+ withpen pencircle scaled 2mm
+ withcolor darkgreen
+ withtransparency (1,.5) ;
+ drawpoints e ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[e] \startlinecorrection \getbuffer[testpath,e] \stoplinecorrection
+
+This looks okay compared to previous the examples but we have only a simple path
+here, while the fill actually has two:
+
+\startbuffer[e]
+\startMPcode
+ pen p ; p := makepen(unitsquare rotated eps) ;
+ enfill fullcircle xyscaled (.8TextWidth,2cm)
+ withpen p scaled 8mm
+ withcolor darkgreen
+ withtransparency (1,.5) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[e] \startlinecorrection \getbuffer[testpath,e] \stoplinecorrection
+
+So how do we get that inner shape? Once you know what a fill actually outputs to
+the backend it is easy! There are two envelopes: the normal one and one made from
+the reverse path (or in internal \METAPOST\ speak: htap). In the previous example
+the \type {enfill} treats the path as a fill but will draw the envelopes instead.
+As with \type {eofill}, \type {eoclip} and path accumulators this is a \METAFUN\
+backend related feature but we introduced \type {enfill} as a new one.
+
+\startbuffer[e]
+\startMPcode
+ pen p ; p := makepen(unitsquare rotated eps) ;
+ draw
+ envelope (p scaled 8mm) of
+ (fullcircle xyscaled (.8TextWidth,2cm))
+ withpen pencircle scaled 2mm
+ withcolor darkgreen
+ withtransparency (1,.5) ;
+ draw
+ envelope (p scaled 8mm) of
+ reverse (fullcircle xyscaled (.8TextWidth,2cm))
+ withpen pencircle scaled 2mm
+ withcolor darkblue
+ withtransparency (1,.5) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[e] \startlinecorrection \getbuffer[testpath,e] \stoplinecorrection
+
+We're now ready for the real deal but keep in mind that what we show here is the
+result of stepwise growing insight combined with adding some features to the
+engine that not only makes it possible to illustrate this but also might prove to
+be useful. The used primitives will be explained later, for now we just stick
+to the results.
+
+\startMPextensions
+ def pentest (expr pth, psh, convex, enhance, width) =
+ image (
+ save p, s, w, pp, somepen ;
+ numeric s ; s := width ;
+ numeric w ; w := (15/100)*s ;
+
+ path p, e, pp, somepen ;
+
+ p := pth scaled s ;
+
+ % gets rid of bad end condition (rectangle) (introduced close points)
+
+ pp := psh rotated eps ;
+
+ if convex :
+ pen somepen ; somepen := makepen (pp) ;
+ else :
+ nep somepen ; somepen := makenep (pp) ;
+ fi ;
+
+ if cycle p : fill else : draw fi p
+ withcolor blue
+ withpen somepen scaled w
+ withtransparency (1,.5)
+ ;
+ drawarrow p ;
+ drawpoints p ;
+
+ path ppp ; ppp := pp scaled w;
+ path qqq ; qqq := convexed ppp;
+
+ for i within p :
+ drawarrow qqq shifted pathpoint withcolor yellow dashed evenly withpen pencircle scaled 1;
+ drawarrow ppp shifted pathpoint withcolor white;
+ drawpoints ppp shifted pathpoint withcolor white ;
+ endfor ;
+
+ % for i within arcpointlist 50 of p :
+ % draw ppp shifted pathpoint withcolor white ;
+ % endfor ;
+
+ defaultscale := .4 ;
+ e := envelope somepen scaled w of p ;
+ % e := e scrutinized 0.01 ;
+ draw e withcolor darkgreen withpen pencircle scaled 1mm;
+ drawpoints e ;
+ % drawpointlabels e withcolor green ;
+ e := envelope somepen scaled w of reverse p ;
+ % e := e scrutinized 0.01 ;
+ draw e withcolor yellow withpen pencircle scaled 1mm;
+ drawpoints e ;
+ % drawpointlabels e withcolor yellow ;
+
+ if enhance :
+ e := e scrutinized 0.01 ;
+ draw convexed e withcolor darkmagenta withpen pencircle scaled 2mm ;
+ fi ;
+
+ )
+ enddef ;
+\stopMPextensions
+
+\startMPextensions
+ def TestShapesA(expr pth, convex, enhance, dy) =
+ draw pentest (pth, fullcircle, convex, enhance, .4TextWidth) shifted ( 0, 0) ;
+ draw pentest (pth, fulldiamond, convex, enhance, .4TextWidth) shifted (.5TextWidth, 0) ;
+ draw pentest (pth, fulltriangle, convex, enhance, .4TextWidth) shifted ( 0,dy*TextWidth) ;
+ draw pentest (pth, fullsquare, convex, enhance, .4TextWidth) shifted (.5TextWidth,dy*TextWidth) ;
+ enddef ;
+
+ def TestShapesB(expr pth, convex, enhance, dy) =
+ draw pentest (pth, starring(-1/3), convex, enhance, .35TextWidth) shifted ( 0, 0) ;
+ draw pentest (pth, starring(-1/2), convex, enhance, .35TextWidth) shifted (.5TextWidth, 0) ;
+ draw pentest (pth, starring(-eps), convex, enhance, .35TextWidth) shifted ( 0,dy*TextWidth) ;
+ draw pentest (pth, starring(-1/2), convex, enhance, .35TextWidth) shifted (.5TextWidth,dy*TextWidth) ;
+ enddef ;
+\stopMPextensions
+
+\startplacefigure[reference=fig:A:T:F:1,title={Using four different relatively large pens on a circle.}]
+ \startMPcode
+ TestShapesA(fullcircle, true, false, .5) ;
+ \stopMPcode
+\stopplacefigure
+
+\in {Figure} [fig:A:T:F:1] shows a circle filled (or enveloped) with pens made from
+\type {fullcircle}, \type {fulldiamond}, \type {fulltriangle} and \type
+{fullsquare}. The paths that we use for the pens are also shown. The outcome can
+be puzzling but after going over the code (in the engine) and trying to reason
+the logic it becomes clear that the unexpected is mostly due to the fact that
+there is no other way to draw the path (read: meet the criteria).
+
+When looking closely at the results (adding labels to the points and zooming in)
+one will notice more side effects. Because we rotate over \type {eps} to get rid
+of the weird end situation we can end up with more points than we like and these
+are so close to each other that one doesn't notice them. For this we can apply
+the scrutinizer:
+
+\starttyping
+e := e scrutinized 0.01 ;
+\stoptyping
+
+When that is done we can wonder if a simplified (inner) path is possible. I tried
+a few solutions using the \LUA\ interface while Mikael (as mathematician)
+followed the more scientific approach but the results largely depend on the pens
+and shapes.
+
+\startplacefigure[reference=fig:B:T:F:1]
+ \startMPcode
+ TestShapesB(fullcircle, true, false, .5) ;
+ \stopMPcode
+\stopplacefigure
+
+Actually when doing all that we used a more complex pen in several variants. This
+is shown in \in {figure} [fig:B:T:F:1]. Notice the dashed lines here. When a pen
+is defined there is some checking going on. One is that circular pens get no
+treatment at all and just pass through the system. Basically any single point
+cycle is considered as elliptical anyway. Then the path turned into a so called
+\quote {convex} path. It also showed us the real pen being used. When out of
+curiosity I commented that bit of code I noticed that we could achieve
+interesting results. The result is that we now have a \type {convexed} primitive.
+After all the code was there so it took only a few lines to add this primitive.
+In \in {figure} [fig:B:F:F:1] you can see the result of a unconvexed pen.
+
+\startplacefigure[reference=fig:B:F:F:1]
+ \startMPcode
+ TestShapesB(fullcircle, false, false, .5) ;
+ \stopMPcode
+\stopplacefigure
+
+We can also calculate envelopes of non|-|cyclic paths which is demonstrated in
+\in {figure} [fig:B:T:F:2] and \in {figure} [fig:B:F:F:2]. There is however some
+trickery involved. Just to make this easier the \METAFUN\ macro package has a
+type {starring} macro that makes such a star:
+
+\starttyping
+path p ; p := starring(-1/2) rotated eps ;
+\stoptyping
+
+This star can become a pen:
+
+\starttyping
+pen somepen ; somepen := makepen (pp) ;
+\stoptyping
+
+And as mentioned pens get convexed by default. Even worse, whenever we transform
+a pen it gets convexed again. When we fill a shape the pen gets attached to that shape
+and the backend will do the enveloping. The easiest way to consistently avoid
+convexing was to introduce a new pen type.
+
+\starttyping
+nep somepen ; somepen := makenep (pp) ;
+\stoptyping
+
+The somewhat weird short \type {nep} perfectly fits the bill as in Dutch it means
+fake. A pen defined this way stays unconvexed. Actually there is another property
+where pens differ from regular paths: they are double linked. In original
+\METAPOST\ that back (prev) link uses a field in a knot record that is not used
+by pen paths. The path that gets pencilled also abuses one of knot fields for
+keeping track of the offset that a point has relative to the current point in the
+pen. It was good moment to also make regular paths double linked lists. That
+comes at the cost of an extra pointer in the knot record but we could also save
+some space by using smaller slots for other fields. Memory is not our biggest
+worry anyway. \footnote {Of course adding code is but when looking in more detail
+at the code involved it was actually possible to simplify the code a bit so there
+we gained}. Double linking meant that there was no need for doing that when
+making pens. \footnote {It makes it possible to get points relative to the
+current point in iterators over paths that we introduced a while ago, which makes
+for high performance path manipulators.}
+
+\startplacefigure[reference=fig:B:T:F:2]
+ \startMPcode
+ TestShapesB((0,0) -- (1/2,1/2) -- (2/2,0), true, false, .35) ;
+ \stopMPcode
+\stopplacefigure
+
+\startplacefigure[reference=fig:B:F:F:2]
+ \startMPcode
+ TestShapesB((0,0) -- (1/2,1/2) -- (2/2,0), false, false, .35) ;
+ \stopMPcode
+\stopplacefigure
+
+We can apply the \type {convexed} primitive to the inner envelope which is demonstrated
+in \in {figure} [fig:B:T:T:3] and \in {figure} [fig:B:F:T:3]. Of course it is debatable
+how useful this is but as with all these \METAPOST\ shapes, it has some charm.
+
+\startplacefigure[reference=fig:B:T:T:3]
+ \startMPcode
+ TestShapesB(fullcircle, true, true, .5) ;
+ \stopMPcode
+\stopplacefigure
+
+\startplacefigure[reference=fig:B:F:T:3]
+ \startMPcode
+ TestShapesB(fullcircle, false, true, .5) ;
+ \stopMPcode
+\stopplacefigure
+
+% \startplacefigure[reference=fig:B:T:F:2]
+% \startMPcode
+% TestShapesB((0,0) -- (1/2,1/2) -- (2/2,0) -- cycle, true, false) ;
+% \stopMPcode
+% \stopplacefigure
+
+% \startplacefigure[reference=fig:B:F:F:2]
+% \startMPcode
+% TestShapesB((0,0) -- (1/2,1/2) -- (2/2,0) -- cycle, false, false) ;
+% \stopMPcode
+% \stopplacefigure
+
+% \startMPpage[offset=1dk]
+% enfill fullcircle scaled 2cm withpen makepen(fullsquare) scaled 1pt withcolor darkred ;
+% enfill fullcircle scaled 3cm withpen makepen(fullsquare) scaled 1pt withcolor darkblue ;
+% enfill reverse fullcircle scaled 1cm withpen makepen(fullsquare) scaled 1pt withcolor darkgreen ;
+% \stopMPpage
+
+% \startMPpage[offset=1dk]
+% draw envelope makepen(fullsquare) of ( fullcircle scaled 2cm) withpen pencircle scaled 1pt withcolor darkred ;
+% draw envelope makepen(fullsquare) of (reverse fullcircle scaled 3cm) withpen pencircle scaled 1pt withcolor darkblue ;
+% draw envelope makepen(reverse fullsquare) of ( fullcircle scaled 1cm) withpen pencircle scaled 1pt withcolor darkgreen ;
+% \stopMPpage
+
+\page
+
+To what extend does all this influence the output? As long as we don't use
+transparencies we're quite okay unless we use a pen size that introduces the more
+extreme overshoots. If you think these phenomena only relate to \METAPOST\
+output, you're wrong. Over the past decades I've seen various fonts that exhibit
+the same small spikes and other artifacts btu as we often see the shapes at small
+sizes it goes unnoticed. A particular sensitive areas is variable fonts where,
+when the ranges on which the various dimensions operate are too liberal, you can
+also get these effects. After all, glyphs are filled shapes. To that you can also
+add the fact that they are single (connected) paths drawn with \type {eofill}.
+
+The final format a graphics ends up in can be \PDF. Take the following three
+shapes and watch the subtle side effect of rotating either the to be drawn shape
+or the pen.
+
+\startbuffer[e]
+\startMPcode
+ fill fullcircle xyscaled (5cm,3cm)
+ withpen makepen(fullsquare) scaled 2mm
+ withcolor darkred
+ withtransparency (1,.5) ;
+ fill fullcircle xyscaled (5cm,3cm)
+ shifted (6cm,0)
+ withpen makepen(fullsquare rotated eps) scaled 2mm
+ withcolor darkblue
+ withtransparency (1,.5) ;
+ fill fullcircle rotated eps xyscaled (5cm,3cm)
+ shifted (12cm,0)
+ withpen makepen(fullsquare) scaled 2mm
+ withcolor darkgreen
+ withtransparency (1,.5) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[e] \startlinecorrection \getbuffer[e] \stoplinecorrection
+
+This produces four filled paths in the \PDF\ file, a normal and a reverse path
+per shape. I show the whole output because you can see how some points of the
+\quote {inside} curve are sort of duplicated: they have the same coordinates but
+can have different control points.
+
+\starttabulate[|lT|lT|lT|]
+\BC \BC inner \BC outer \NC \NR
+\BC left \NC 25=26 31=32 35=36 39=40 43=25 \NC \NC \NR
+\BC middle \NC \NC 49=50=51 54=55 58=59 62=63 \NC \NR
+\BC right \NC 107=108=109 112=113 116=117 120=121 \NC 89=105 \NC \NR
+\stoptabulate
+
+Here is the output. Each combination is between bound by the transparency
+operators \type {/Tr1} and \type {/Tr0} and has different colors.
+
+\startlinenumbering
+\starttyping
+% mps graphic 1: begin
+q
+/Tr1 gs
+0.625 0 0 rg 0.625 0 0 RG
+10 M
+1 j
+ 45.354315 2.83464 m
+ 45.354315 14.111559 40.874577 24.926605 32.900591 32.900591 c
+ 24.926605 40.874577 14.111559 45.354315 2.83464 45.354315 c
+ 2.83464 45.354315 -2.83464 45.354315 -2.83464 45.354315 c
+ -2.83464 45.354315 l
+-14.111559 45.354315 -24.926605 40.874577 -32.900591 32.900591 c
+-40.874577 24.926605 -45.354315 14.111559 -45.354315 2.83464 c
+-45.354315 2.83464 -45.354315 -2.83464 -45.354315 -2.83464 c
+-45.354315 -2.83464 l
+-45.354315 -14.111559 -40.874577 -24.926605 -32.900591 -32.900591 c
+-24.926605 -40.874577 -14.111559 -45.354315 -2.83464 -45.354315 c
+-2.83464 -45.354315 2.83464 -45.354315 2.83464 -45.354315 c
+2.83464 -45.354315 l
+14.111559 -45.354315 24.926605 -40.874577 32.900591 -32.900591 c
+40.874577 -24.926605 45.354315 -14.111559 45.354315 -2.83464 c
+45.354315 -2.83464 45.354315 2.83464 45.354315 2.83464 c
+45.354315 2.83464 l
+h f
+39.685035 -2.83464 m
+39.685035 -2.83464 45.354315 -2.83464 45.354315 -2.83464 c
+45.354315 -2.83464 45.354315 2.83464 45.354315 2.83464 c
+45.354315 2.83464 39.685035 2.83464 39.685035 2.83464 c
+39.685035 -8.442279 35.205297 -19.257325 27.231311 -27.231311 c
+19.257325 -35.205297 8.442279 -39.685035 -2.83464 -39.685035 c
+-2.83464 -39.685035 l
+-2.83464 -39.685035 2.83464 -39.685035 2.83464 -39.685035 c
+-8.442279 -39.685035 -19.257325 -35.205297 -27.231311 -27.231311 c
+-35.205297 -19.257325 -39.685035 -8.442279 -39.685035 2.83464 c
+-39.685035 2.83464 l
+-39.685035 2.83464 -39.685035 -2.83464 -39.685035 -2.83464 c
+-39.685035 8.442279 -35.205297 19.257325 -27.231311 27.231311 c
+-19.257325 35.205297 -8.442279 39.685035 2.83464 39.685035 c
+2.83464 39.685035 l
+2.83464 39.685035 -2.83464 39.685035 -2.83464 39.685035 c
+8.442279 39.685035 19.257325 35.205297 27.231311 27.231311 c
+35.205297 19.257325 39.685035 8.442279 39.685035 -2.83464 c
+39.685035 -2.83464 l
+h f
+/Tr0 gs
+0 g 0 G
+/Tr1 gs
+0 0 0.625 rg 0 0 0.625 RG
+158.740139 -2.834616 m
+158.740139 -2.834252 l
+158.740139 -2.834252 158.740091 2.835028 158.740091 2.835028 c
+158.739994 14.111816 154.260267 24.926715 146.286366 32.900615 c
+138.31238 40.874601 127.497335 45.354339 116.220416 45.354339 c
+116.220052 45.354339 l
+116.220052 45.354339 110.550772 45.354291 110.550772 45.354291 c
+99.273984 45.354194 88.459085 40.874467 80.485185 32.900566 c
+72.511199 24.92658 68.031461 14.111535 68.031461 2.834616 c
+68.031461 2.834252 l
+68.031461 2.834252 68.031509 -2.835028 68.031509 -2.835028 c
+68.031606 -14.111816 72.511333 -24.926715 80.485234 -32.900615 c
+88.45922 -40.874601 99.274265 -45.354339 110.551184 -45.354339 c
+110.551548 -45.354339 l
+110.551548 -45.354339 116.220828 -45.354291 116.220828 -45.354291 c
+127.497616 -45.354194 138.312515 -40.874467 146.286415 -32.900566 c
+154.260401 -24.92658 158.740139 -14.111535 158.740139 -2.834616 c
+h f
+153.070811 2.834616 m
+153.070811 -8.442303 148.591072 -19.257349 140.617086 -27.231335 c
+132.643186 -35.205235 121.828288 -39.684963 110.5515 -39.685059 c
+110.5515 -39.685059 116.22078 -39.685011 116.22078 -39.685011 c
+116.220416 -39.685011 l
+104.943497 -39.685011 94.128451 -35.205272 86.154465 -27.231286 c
+78.180565 -19.257386 73.700837 -8.442488 73.700741 2.8343 c
+73.700741 2.8343 73.700789 -2.83498 73.700789 -2.83498 c
+73.700789 -2.834616 l
+73.700789 8.442303 78.180528 19.257349 86.154514 27.231335 c
+94.128414 35.205235 104.943312 39.684963 116.2201 39.685059 c
+116.2201 39.685059 110.55082 39.685011 110.55082 39.685011 c
+110.551184 39.685011 l
+121.828103 39.685011 132.643149 35.205272 140.617135 27.231286 c
+148.591035 19.257386 153.070763 8.442488 153.070859 -2.8343 c
+153.070859 -2.8343 153.070811 2.83498 153.070811 2.83498 c
+153.070811 2.834616 l
+h f
+/Tr0 gs
+0 g 0 G
+/Tr1 gs
+0 0.625 0 rg 0 0.625 0 RG
+272.125915 2.835004 m
+272.125819 14.111923 267.645988 24.92693 259.671934 32.900848 c
+251.697965 40.87468 240.883028 45.354315 229.606241 45.354315 c
+229.606241 45.354315 223.936961 45.354315 223.936961 45.354315 c
+223.936596 45.354315 l
+212.659677 45.354219 201.84467 40.874388 193.870752 32.900334 c
+185.89692 24.926365 181.417285 14.111428 181.417285 2.834641 c
+181.417285 2.834641 181.417285 -2.834639 181.417285 -2.834639 c
+181.417285 -2.835004 l
+181.417381 -14.111923 185.897212 -24.92693 193.871266 -32.900848 c
+201.845235 -40.87468 212.660172 -45.354315 223.936959 -45.354315 c
+223.936959 -45.354315 229.606239 -45.354315 229.606239 -45.354315 c
+229.606604 -45.354315 l
+240.883523 -45.354219 251.69853 -40.874388 259.672448 -32.900334 c
+267.64628 -24.926365 272.125915 -14.111428 272.125915 -2.834641 c
+272.125915 -2.834641 272.125915 2.834639 272.125915 2.834639 c
+272.125915 2.835004 l
+h f
+266.456635 -2.834276 m
+266.456635 -2.834641 l
+266.456635 -2.834641 266.456635 2.834639 266.456635 2.834639 c
+266.456635 -8.442148 261.977 -19.257085 254.003168 -27.231054 c
+246.02925 -35.205108 235.214243 -39.684939 223.937324 -39.685035 c
+223.936959 -39.685035 l
+223.936959 -39.685035 229.606239 -39.685035 229.606239 -39.685035 c
+218.329452 -39.685035 207.514515 -35.2054 199.540546 -27.231568 c
+191.566492 -19.25765 187.086661 -8.442643 187.086565 2.834276 c
+187.086565 2.834641 l
+187.086565 2.834641 187.086565 -2.834639 187.086565 -2.834639 c
+187.086565 8.442148 191.5662 19.257085 199.540032 27.231054 c
+207.51395 35.205108 218.328957 39.684939 229.605876 39.685035 c
+229.606241 39.685035 l
+229.606241 39.685035 223.936961 39.685035 223.936961 39.685035 c
+235.213748 39.685035 246.028685 35.2054 254.002654 27.231568 c
+261.976708 19.25765 266.456539 8.442643 266.456635 -2.834276 c
+h f
+/Tr0 gs
+0 g 0 G
+Q
+% mps graphic 1: end
+\stoptyping
+\stoplinenumbering
+
+The duplicates differ per variant and as they are effective \type {lineto}
+combine with \type {curveto} we can consider removing the \type {lineto}'s. This
+can either be done in the backend or we can decide to do that in the \METAPOST\
+library during the export. \footnote {In the end I settled on introducing a move
+tolerance in addition to the bend tolerance that we already have in the export.
+The default value of \cldcontext {"\letterpercent .6N", metapost .
+getmovetolerance ()} removes 14 lines from the above \PDF\ code.}
+
+The \type {tracingspecs} flag can help us to see what happens deep down when
+
+envelopes are made. It will show the intermediate path on the console.
+
+\starttyping
+tracingspecs := 1;
+path e ; e := envelope (makepen(fullsquare) scaled 2mm) of (fullcircle scaled 3cm) ;
+show(e);
+\stoptyping
+
+The intermediate path is reported as:
+
+\starttyping
+ % beginning with offset ( 2.83464, 2.83464)
+ ( 42.51968, 0 ) .. controls ( 42.51968, 11.27742) and ( 38.03908, 22.09160)
+.. ( 30.06534, 30.06534) .. controls ( 22.09160, 38.03908) and ( 11.27742, 42.51968)
+ % counterclockwise to offset (-2.83464, 2.83464)
+.. ( 0, 42.51968) .. controls ( 0, 42.51968) and ( 0, 42.51968)
+.. ( 0, 42.51968) .. controls (-11.27742, 42.51968) and (-22.09160, 38.03908)
+.. (-30.06534, 30.06534) ..controls (-38.03908, 22.09160) and (-42.51968, 11.27742)
+ % counterclockwise to offset (-2.83464,-2.83464)
+.. (-42.51968, 0 ) .. controls (-42.51968, 0 ) and (-42.51968, 0 )
+.. (-42.51968, 0 ) .. controls (-42.51968,-11.27742) and (-38.03908,-22.09160)
+.. (-30.06534,-30.06534) .. controls (-22.0916, -38.03908) and (-11.27742,-42.51968)
+ % counterclockwise to offset ( 2.83464,-2.83464)
+.. ( 0, -42.51968) .. controls ( 0, -42.51968) and ( 0, -42.51968)
+.. ( 0, -42.51968) .. controls ( 11.27742,-42.51968) and ( 22.0916, -38.03908)
+.. ( 30.06534,-30.06534) .. controls ( 38.03908,-22.09160) and ( 42.51968,-11.27742)
+ % counterclockwise to offset ( 2.83464, 2.83464)
+.. ( 42.51968, 0 ) .. controls ( 42.51968, 0 ) and ( 42.51968, 0 )
+.. ( 42.51968, 0 )
+& cycle
+\stoptyping
+
+The result becomes:
+
+\starttyping
+ ( 45.35432, 2.83464) .. controls ( 45.35432, 14.11206) and ( 40.87372, 24.92624)
+.. ( 32.89998, 32.89998) .. controls ( 24.92624, 40.87372) and ( 14.11206, 45.35432)
+.. ( 2.83464, 45.35432) .. controls ( 2.83464, 45.35432) and ( -2.83464, 45.35432)
+.. ( -2.83464, 45.35432) .. controls ( -2.83464, 45.35432) and ( -2.83464, 45.35432)
+.. ( -2.83464, 45.35432) .. controls (-14.11206, 45.35432) and (-24.92624, 40.87372)
+.. (-32.89998, 32.89998) .. controls (-40.87372, 24.92624) and (-45.35432, 14.11206)
+.. (-45.35432, 2.83464) .. controls (-45.35432, 2.83464) and (-45.35432, -2.83464)
+.. (-45.35432, -2.83464) .. controls (-45.35432, -2.83464) and (-45.35432, -2.83464)
+.. (-45.35432, -2.83464) .. controls (-45.35432,-14.11206) and (-40.87372,-24.92624)
+.. (-32.89998,-32.89998) .. controls (-24.92624,-40.87372) and (-14.11206,-45.35432)
+.. ( -2.83464,-45.35432) .. controls ( -2.83464,-45.35432) and ( 2.83464,-45.35432)
+.. ( 2.83464,-45.35432) .. controls ( 2.83464,-45.35432) and ( 2.83464,-45.35432)
+.. ( 2.83464,-45.35432) .. controls ( 14.11206,-45.35432) and ( 24.92624,-40.87372)
+.. ( 32.89998,-32.89998) .. controls ( 40.87372,-24.92624) and ( 45.35432,-14.11206)
+.. ( 45.35432, -2.83464) .. controls ( 45.35432, -2.83464) and ( 45.35432, 2.83464)
+.. ( 45.35432, 2.83464) .. controls ( 45.35432, 2.83464) and ( 45.35432, 2.83464)
+.. cycle
+\stoptyping
+
+Numerous experiments by Mikael and me lead to the conclusion that both stages can
+introduce the duplicate points and that any messing with that during envelop
+generation time has negative side effects. However, when we export the path we
+can definitely get rid of them. They are harmless but we're talking quality
+control here and \TEX\ and \METAPOST\ is all about quality!
+
+As usual, playing with mechanisms like this gets one wondering about similar cases,
+for instance variants of dashing.
+
+\startbuffer[e]
+\startMPcode
+vardef dashing (expr pth, shp, stp) =
+ for i within arcpointlist stp of pth :
+ shp
+ rotated angle(pathdirection)
+ shifted pathpoint
+ &&
+ endfor nocycle
+enddef ;
+
+path parrA ; parrA :=
+ (0,0) -- (0,-1) -- (2,-1) -- (2,-2) -- (4,0) -- (2,2) -- (2,1) -- (0,1) -- (0,0)
+;
+path parrB ; parrB :=
+ parrA -- (0,-1) -- (2,-1) -- (2,-2) -- (4,0)
+;
+path p ; p := fullcircle scaled 2cm ;
+
+fill (dashing (p, parrA, 25) && cycle) withtransparency (1,.5) ;
+draw (dashing (p, parrA, 25) && cycle) withtransparency (1,.5) ;
+fill (dashing (p, parrB, 25) && cycle) shifted (3cm,0) withtransparency (1,.5) ;
+draw (dashing (p, parrB, 25) && cycle) shifted (3cm,0) withtransparency (1,.5) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[e]
+
+In \in {figure} [fig:DASHING:1] we see the result. Of course how well if comes out
+depends on the definition but what is special here is that we use the double
+ampersand operator. That one will connect the paths without complaining about the
+end and being point not colliding. I suppose there was a good reason for making
+that a condition in the case of fonts, after all \METAFONT\ is what it came from,
+but there is no real reason for it. It is a cheap extension anyway. At the same
+time I decided to add a native \quote {direction} operator. The number of extra
+bytes in the binary is probably less than what is needed in memory to store the
+macro and the advantage is that we save an extra run over the path to reach the
+point we're consulting. \footnote {In case you wonder, \ this is how the macro
+definition looks like: \typ {vardef direction expr t of p = postcontrol t of p -
+precontrol t of p enddef ;}. Because points are searched from from the start
+there are two lookups needed. Normally this is no problem but Mikael and I are
+playing with really large paths, like those that come from drawing functions.}
+
+\startplacefigure[reference=fig:DASHING:1,title=A somewhat related rendering.]
+ \scale[width=\textwidth]{\getbuffer[e]}
+\stopplacefigure
+
+In case you wonder why we need this feature, here is an argument:
+
+\startbuffer[e]
+\startMPcode
+ path s ; s := fullcircle scaled 4cm ; pickup pencircle scaled 5mm ;
+
+ draw (s shifted (0cm,0) && s shifted (3cm,0) && s shifted (6cm,0))
+ withcolor "darkred" withtransparency (1,.5) ;
+
+ currentpicture := currentpicture shifted (-8cm,0) ;
+
+ draw s shifted (0cm,0)
+ withcolor "darkblue" withtransparency (1,.5) ;
+ draw s shifted (3cm,0)
+ withcolor "darkblue" withtransparency (1,.5) ;
+ draw s shifted (6cm,0)
+ withcolor "darkblue" withtransparency (1,.5) ;
+
+ currentpicture := currentpicture shifted (-8cm,0) ;
+
+ nodraw s shifted (0cm,0) ;
+ nodraw s shifted (3cm,0) ;
+ nodraw s shifted (6cm,0) ;
+ dodraw origin withcolor "darkgreen" withtransparency (1,.5) ;
+
+\stopMPcode
+\stopbuffer
+
+\typebuffer[e]
+
+The results are shown in \in {figure} [fig:DASHING:2]. Which if the alternatives
+you prefer also depends on how you generate the shape. The \type {nodraw} variant
+for instance can be mixed with calculations without the need to revert to \type
+{hide}.
+
+\startplacefigure[reference=fig:DASHING:1,title=Do you see the difference?]
+ \scale[width=\textwidth]{\getbuffer[e]}
+\stopplacefigure
+
+\startbuffer[e]
+\startMPcode
+vardef dashing (expr pth, shp, stp) =
+ for i within arcpointlist stp of pth :
+ shp
+ rotated angle(pathdirection)
+ shifted pathpoint
+ &&
+ endfor nocycle
+enddef ;
+
+path e, p ; numeric n ;
+e := (0,0) -- (0,-1) -- (2,-1) -- (2,-2) -- (4,0) -- (2,2) -- (2,1) -- (0,1) -- (0,0) ;
+n := 10 * bbwidth(e) ;
+p := function(1,"x","x/4 + sin(x)",epsed(0.1),epsed(4*pi),0.01) scaled 2cm ;
+
+fill (dashing (p, e scaled 2.5, n) && cycle) withcolor .6white ;
+draw (dashing (p, e scaled 2.5, n) && cycle) withcolor darkgreen ;
+
+currentpicture := currentpicture shifted (0,-2cm) ;
+
+n := 20 * bbwidth(e) ;
+fill (dashing (p, e, n) && cycle) withcolor .6white ;
+draw (dashing (p, e, n) && cycle) withcolor darkblue ;
+\stopMPcode
+\stopbuffer
+
+\in {Figure} [fig:DASHING:3] demonstrates how far we've come. Mikaels fancy
+arrows nicely follow the shape of the function. Of course you need to make sure
+that these arrows are reasonably scaled. The definition of \type {dashing}
+demonstrates a few primitives that permits efficient iteration over a path and
+\type {arcpointlist} is sort of a path.
+
+\startplacefigure[reference=fig:DASHING:3,title=Advanced pseudo dashing.]
+ \scale[width=\textwidth]{\getbuffer[e]}
+\stopplacefigure
+
+\typebuffer[e]
+
+\stopchapter
+
+\stopcomponent
+
+% \startMPpage[offset=1dk]
+% path theta, xaxis, yaxis;
+%
+% xaxis := (-4, 0) -- (5, 0) ;
+% yaxis := ( 0,-2) -- (0, 2) ;
+% theta := (-3, 0) -- (0, 0) &&
+% ( 0, 1) -- (3, 1) &&
+% ( 3,-1) -- (5,-1) ;
+%
+% draw theta scaled 2cm
+% withpen pencircle scaled 2
+% withcolor darkred ;
+%
+% drawarrow xaxis scaled 2cm ;
+% drawarrow yaxis scaled 2cm ;
+% \stopMPpage
+
+% \startMPpage[offset=1dk]
+% vardef dashing (expr pth, shp, stp) =
+% for i within arcpointlist stp of pth :
+% shp
+% rotated angle(pathdirection)
+% shifted pathpoint
+% &&
+% endfor nocycle
+% enddef ;
+%
+% path e, p ; numeric n ;
+% e := (0,0) -- (0,-1) -- (2,-1) -- (2,-2) -- (4,0) -- (2,2) -- (2,1) -- (0,1) -- (0,0) ;
+% n := 30 * bbwidth(e) ; % 80 ;
+% p := function(1,"x","x/4 + sin(x)",epsed(0.1),epsed(4*pi),0.01) scaled 2cm ;
+
+% % draw p withpen pencircle scaled .1mm withcolor darkblue ;
+
+% eofill (dashing (p, e, n) && cycle) withcolor .6white ; % withtransparency (1,.5) ;
+% draw (dashing (p, e, n) && cycle) withcolor darkgreen ; % withtransparency (1,.5) ;
+% \stopMPpage
+
+% \startMPpage[offset=1dk]
+% path theta, xaxis, yaxis;
+%
+% xaxis := (-4,0) -- (4,0) ;
+% yaxis := (0,-1/4) -- (0,3/2) ;
+% theta := (-3,0) -- (0,0) && (0,1) -- (3,1) ;
+%
+% pickup pencircle scaled 1mm;
+%
+% drawarrow xaxis scaled 2cm ;
+% drawarrow yaxis scaled 2cm ;
+% draw theta scaled 2cm withcolor darkred ;
+%
+% currentpicture := currentpicture shifted (0,5cm) ;
+%
+% drawarrow xaxis scaled 2cm ;
+% drawarrow yaxis scaled 2cm ;
+%
+% draw (theta && cycle) scaled 2cm withcolor darkyellow ;
+% drawpoints (theta && cycle) scaled 2cm withcolor darkyellow ;
+% drawpointlabels (theta && cycle) scaled 2cm withcolor darkyellow ;
+% fill (theta && cycle) scaled 2cm withcolor "orange" withpen pencircle scaled .5mm;
+%
+% show(theta );
+% show(theta && cycle);
+%
+% \stopMPpage
+
+% \startMPpage[offset=1dk]
+% path theta, xaxis, yaxis, thetaA, thetaB ;
+%
+% xaxis := (-4,0) -- (4,0) ;
+% yaxis := (0,-1/4) -- (0,3/2) ;
+%
+% thetaA := (-3,0) -- (0,0) -- (-2,1) -- cycle ;
+% thetaB := ( 0,1) -- (3,1) -- ( 2,0) -- cycle ;
+% theta := thetaA && thetaB ;
+%
+% pickup pencircle scaled 1mm;
+%
+% drawarrow xaxis scaled 2cm ;
+% drawarrow yaxis scaled 2cm ;
+% draw theta scaled 2cm withcolor darkred ;
+%
+% currentpicture := currentpicture shifted (0,5cm) ;
+%
+% drawarrow xaxis scaled 2cm ;
+% drawarrow yaxis scaled 2cm ;
+%
+% draw (theta && cycle) scaled 2cm withcolor darkyellow ;
+% fill (theta && cycle) scaled 2cm withcolor "orange" withpen pencircle scaled .5mm;
+% \stopMPpage
+
+% \startMPpage
+% picture q ; q := lmt_outline [ text = "\TEX", kind = "path" ] ;
+% path qq ; qq := for i within q :
+% if picture i : for j within i : if stroked j :
+% pathpart j &&
+% fi endfor fi
+% endfor nocycle ;
+%
+% path e, p ; numeric n ;
+% e := qq shifted - center qq xsized 1mm ;
+% n := 30 * bbwidth(e) ;
+% p := function(1,"x","x/4 + sin(x)",epsed(0.1),epsed(4*pi),0.01) scaled 2cm ;
+%
+% draw (dashing (p, e scaled 2.5, n) && cycle)
+% withpen pencircle scaled .1
+% withcolor darkgreen
+% ;
+%
+% path e, p ; numeric n ;
+% e := qq shifted - center qq xsized .1mm ;
+% n := 2000 * bbwidth(e) ;
+% p := function(1,"x","x/4 + sin(x)",epsed(0.1),epsed(4*pi),0.01) scaled 2cm ;
+
+% draw (dashing (p, e scaled 2.5, n) && cycle)
+% withpen pencircle scaled .01
+% withcolor darkgreen
+% ;
+% \stopMPpage
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-gettingridof.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-gettingridof.tex
index 75b7f5bc040..d87a8d8c9c3 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-gettingridof.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-gettingridof.tex
@@ -118,7 +118,7 @@ we are in r2l mode, just like we look up a smaller variant when we're in compact
font mode (a \CONTEXT\ feature).
\bgroup
-\definefontfeature[mathextra][mathxitsarabic=yes]
+\definefontfeature[mathextra][xitsarabic=yes]
\switchtobodyfont[bonum]
\setupmathematics[bidi=yes,align=righttoleft]\par
\setupalign[righttoleft] %
@@ -182,7 +182,7 @@ but the results are rewarding.
\startformula
\scale[s=2]{\dm{
-\widebar{A}__{\myannuity{m}}^^{2}_{x:\annuity{n}}^{1}
+\widebar{A}__{\myannuity{m}}^^^{2}_{x:\annuity{n}}^{1}
}}
\stopformula
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-green.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-green.tex
new file mode 100644
index 00000000000..ef570c92095
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-green.tex
@@ -0,0 +1,204 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\startcomponent ontarget-green
+
+\environment ontarget-style
+
+\startchapter[title={Running green}]
+
+There are a few contradicting developments going on: energy prices sky|-|rocket
+and Intel and AMD are competing for the fastest \CPU's where saving energy seems
+mostly related to making sure that the many cores running at the same time don't
+burn the machine. However, \TEX\ is a single core consumer so throwing lots of
+cores into the game is not helping much. You're better served with one very fast
+core than many slower ones that accumulate to much horsepower. The later makes
+sense when you process video or play games, but that's not what \TEX\ is about,
+although it is fun to play with. Of course often multiple cores come in handy,
+for instance in the build farm that is used to compile \LUAMETATEX\ and
+intermediate \TEXLIVE\ releases: when that gets compiled and we also trigger a
+\LUAMETATEX\ build, two times 10 \LINUX\ virtual machines are compiling and one
+windows machine that runs four compile jobs at the same time.
+
+The server that runs the farm is Dell 710 server with dual 5630 Xeon processors,
+6 SAS drives each 2GB in (hardware) raid 10, 72 GB memory, redundant power
+supplies and 6 network ports. It sits idle for most of the time and consumes
+between 250 and 400W. It is part of a redundant setup: dual switches, dual
+routers, multiple UPS's, air conditioning, two backup QNAP NAS's, a few low power
+machines for distributed continuous incremental backups, etc. The server itself
+is a refurbished one, so not the most expensive, but with the Dutch energy prices
+of 2022 bound to gas prices, we quickly realized that there was no way we could
+keep it up and running. Because we have three such servers (one is turned off and
+used as fallback) we started wondering if we could go for a different solution.
+
+As we recently upgraded the 2013 laptops to refurbished 2018 ones (the latest
+models that could use the docking stations that we have), we decided to buy a few
+more and test these as replacements for the servers. Of course one has to pimp
+these machines a bit: a professional 2TB nvme SSD plus a proper 2.5in SSD as
+backup one, 64 GB of memory, a few extra USB3 network cards. The \CPU's are fast
+mobile Xeons. We use proxmox as virtual host and that runs fine in such a
+configuration.
+
+Surprisingly, after moving the farm to that setup, which basically boils down to
+moving virtual machines, we found that running those parallel compilations
+performance wise was quite okay. And the nice thing was that these machines idle
+much lower, some 20--30W. The saving is therefore quite noticeable and we decided
+to check some more; after all it would be nice if we could bring down the average
+power consumption of 1750W down to at least half so that it would match the
+output of a few solar panels. Of course it means that one has to ditch perfectly
+well working machines which itself is not that environmental friendly but there
+is not much to choose here.
+
+The second machine to be replaced was the one that runs quite some virtual
+machines too: the main file server, the mail server, an ftp server, the website, an
+rsync host, the squeezebox server that also serves as update test, and various
+project related rendering services. All run in their own (OpenSuse) virtual
+machine. After installing a similar laptop those were also moved.
+
+As a side effect, the two backup NAS's were replaced by a single laptop (my 2013
+Dell precision workhorse) running one backup file server, and for an extra
+incremental backup (rsnaphot running hourly, daily, weekly and monthly backups is
+our friend) a 2013 macbook was turned into a \LINUX\ machine (15W idle with an
+internal reused SSD\footnote {For a change that apple machine was easy to update,
+and we could even get a new clone battery replacement.} and an external 4GB
+disk), two managed switches became one (after all we had less network cables due
+to lost redundancy), only one backup power supply (that will be replaced by an
+nicer alternative when it breaks down; after all, by using laptops we get power
+backup for free). The total consumption went down with at least 1000W. Of course
+there is an investment involved and we need to reconfigure the server rack, but
+the expectation is that by investing now we get less troubles later (less
+gambling on energy). \footnote {We hope to save some 9000 kWh which means that
+save at least some 2500\euro\ per year and more when the government will
+reinstate its energy tax policy and or prices go further up, which seems to be
+the case. Even before the crisis in the Netherlands 5ct/Kwh became fives times
+that amount effectively when connection, transportation, energy tax and value
+added tax gets added.}
+
+But, there is still the pending question of what the impact is on the services
+that we run. The most demanding ones are the Math4all and Math4mbo: these produce
+large files, need many resources (\XML\ and images), and we didn't want to burn
+ourselves too much. Now, here is an interesting observation: this service runs
+twice as fast on the new infrastructure. But it is hard to explain why. The file
+server is on a different machine (so no fast internal network), the \CPU\ is a
+bit faster but not that much, the virtual machine is on \SSD, but files are saved
+on the file server, which is a two disk \USB3 enclosure connected directly to a
+virtual machine that does software raid. The most important difference is that
+main memory is much faster and \TEX\ is a memory intense process. From when we
+started with \LUATEX\ we do know that memory bandwidth and \CPU\ caches makes a
+difference. Maybe the faster floating point handling fo the more modern Xeon also
+helps here.
+
+And that brings me to the following: how do we actually benchmark \TEX ? When you
+go on the internet and compare \CPU's most tests are not that comparable to a
+\TEX\ run on a single core. One can think of a set of test files, but the problem
+there is that when the engine evolves and details in the macro package coding
+changes, one looses the comparison with older tests. This is why, when we do such
+tests, we always run the same test on the different platforms. Although this
+often shows that the gain on newer hardware is seldom what one expects from the
+more general benchmarks, one can still be surprised. When we moved to five year
+newer laptops the gain was some 30\% for me and 50\% for my colleague. The
+difference between his laptop and the slightly more beefed up virtual machine can
+be neglected.
+
+We monitor the power consumption with a youless device connected to the power
+meter. When I process the \LUAMETATEX\ manual I see the phase that the machine
+sits on go up 20W for a run that takes some 9 seconds. Let's say that we use
+180Ws or 0.0006kWh (20.000 runs per kWh). So, compared to the idle power usage of
+a server, a single \TEX\ run can be neglected, simply because it is so fast. So,
+what is actually the most efficient hardware for a \TEX\ service? I get the
+feeling that a decent Intel Atom C3955 16-Core driven machine is quite okay for
+that, but I don't have that at hand and last time I checked one could not order
+anything anyway. And with prices of hardware going up it's also not something you
+try for fun. As comparison to what we have now, testing \TEX\ on an Intel
+NUC11ATKC2 could also be interesting (it has an N4505 \CPU). There was a time
+when I considered a bunch of raspberry pi's but they no longer are that cheap,
+given that you can get them, and adding a case and proper disc enclosure also
+adds up. When wrapped in a nice package the pi will probably a couple of times
+slower but it then probably also uses less power. These fitlets are also
+interesting but again, one can't get them.
+
+It is kind of fun to play with optimizations that don't really impact the clarity
+of the code. One can argue that spending a day on something that saves 0.005
+seconds on a specific run is a waste of time, but of course one has to multiply
+that number by a number of runs. Personally I will never gain from it but
+nevertheless it can save some energy: imagine a batch of 15000 documents every
+day. We then save $15000 * 0.005 * 365 = 27375$ seconds or about 8 hours runtime.
+This can still be neglected but what if this is not the only optimization?
+
+An example of such an optimization is this:
+
+\starttyping
+\advance\somecounter \plusone
+\advance\somecounter by \plusone
+\stoptyping
+
+The second one runs faster because there is no push back involved as side effect of
+the lack of a keyword, so how about adding this to the engine?
+
+\starttyping
+\advanceby \somecounter \plusone
+\advancebyone\somecounter
+\stoptyping
+
+Given the way \LUAMETATEX\ is coded, it only needs a few lines! In this case it
+extends the repertoire of primitives so it is visible but we have many other
+(similarly small) optimizations that contribute. Again, the average user will not
+notice a drop in runtime from 1.5 seconds to 1.45 but when 8 hours become 80
+hours or 800 hours it does become interesting. In energy sensitive 2022 these 800
+hours not only save some \texteuro 400 but also contribute to a lower carbon
+footprint! And now imagine how much could be saved on these extensive runs when
+we make sure that the style used is optimal? Of course, when we need two runs per
+document it starts adding up more.
+
+Some experiments with a demanding file showed one percent gain (on a 2.7 seconds
+run) using the alternative integers, dimensions and advance primitives. However,
+using \CONTEXT's compact font mode brought down runtime to 2.0 seconds! So, in
+the end it's all very relative. It is worth noticing that the .7 seconds saved on
+fonts is sort of constant, which means that accumulated gains elsewhere makes
+that .7 seconds more significant as we progress.
+
+\stopchapter
+
+% 4 * 7520 precision with Xeons
+% 1 * 7600 precision with extreme i7
+% 1 * 2200W dell ups
+% 2 * 4K monitor (+ 3 monitors turned off)
+% 1 * imac server room xubuntu (turned off)
+% 2 * pfsense router (6 port 8 core atom appliances)
+% 1 * dell 48 port switch (1 turned off, 1 24 port switch reserve)
+% 3 * 720 dell server (turned off)
+% 2 * dell 16 port switch
+% 2 * dell 8 port switch (1 turned off)
+% 1 * raspberry pi farm
+% 2 * office printer
+% 4 * standby automatic lights
+% 2 * tv + cable box (+ 1 turned off) (on ups)
+% 2 * hue hub
+% 1 * evohome + pump heating system
+% 1 * airconditioner (idle blow, 28 degrees threshold)
+% 1 * fitlet (serves hue and heating)
+% 1 * fritzbox (7590) + 3 repeaters
+% 1 * cable modem
+% 3 * small UPS
+% 3 * distributed backup (old macbook, hp laptop, hp micro server)
+% - - some standby things (squeeze boxes etc)
+% 32 hue light bulbs
+% 6 * cordless phones
+% 1 * alarm panel
+% 2 * warm water boiler (standby + upping)
+% 1 * coffee machine (standby + upping)
+% 1 * freezer (standby + upping)
+% 1 * refrigerator (standby + upping)
+%
+% 800-1000W (from 1750-2000)
+%
+% (upcoming new monitors will save 100W)
+%
+% aim: 750 during the day, 500 after midnight
+%
+% 4 solar panels on shed
+
+% not mentioned: washing machine, dryer, dish washer, several audio sets,
+% battery loaders (ebike etc),
+
+\stopcomponent
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-introduction.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-introduction.tex
index f7ac0a19d4e..c590269b600 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-introduction.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-introduction.tex
@@ -87,9 +87,13 @@ the boundary for implementing some of the more intrusive extensions in
\LUAMETATEX\ and the follow up on \MPLIB. And once you start along that road
small steps become large steps and one can as well be try to be as complete as
possible. We've come a long way but eventually arrived at the destination.
-Personally I think we got there by not being in a hurry.
+Personally I think we got there by not being in a hurry. Even targets that are
+(nearly) reached can eventually move,
-But even targets that are reached can eventually move,
+I want to use this opportunity to thank Karl Berry. When making some of the
+stories presented here ready for \TUGBOAT, he not only turns bad English into
+good, but also checks and feeds back on what we write. We really appreciate that
+and it also motivates us to keep wrapping up.
\blank[2*big]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-jmn.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-jmn.tex
new file mode 100644
index 00000000000..93d95047c5a
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-jmn.tex
@@ -0,0 +1,245 @@
+% language=us runpath=texruns:manuals/ontarget
+
+% \profilemacro\scaledfontdimen
+
+\usebodyfont[antykwa]
+\usebodyfont[iwona]
+\usebodyfont[kurier]
+
+\startcomponent ontarget-jmn
+
+\environment ontarget-style
+
+\startchapter[title={Supporting math in the JMN collection}]
+
+\startlines
+Hans Hagen, Hasselt NL
+Mikael Sundqvist, Lund SV
+\stoplines
+
+\startsubject[title=Introduction]
+
+In 2022 we overhauled math font support in \CONTEXT, using new functionality in
+the \LUAMETATEX\ engine. By that time it had become clear that the \OPENTYPE\
+math font landscape had more or less settled. The Latin Modern fonts as well as
+the \TEX gyre fonts don't evolve, so we consider them being frozen. It is also
+unlikely that the reference Cambria font will change or become more complete.
+More recent math font are modelled as a mixture of Cambria and Latin Modern.
+
+When we started with \LUATEX\ in \CONTEXT\ we immediately started using \UNICODE\
+math but the lack of proper \UNICODE\ fonts, with the exception of Cambria,
+resulted in creating virtual \UNICODE\ math fonts on the fly using the virtual
+font features of the \LUATEX. But when the \OPENTYPE\ math fonts came available
+that kind of trickery was no longer needed (or at least less preferred).
+
+That is why we considered dropping the virtual math font mechanism from \LMTX. We
+had already dropped \type {tx} (we can use Termes) and \type {px} (better use
+Pagella) fonts as well as \TYPEONE\ based Latin Modern. Dropping the commercial
+Math Times was a logical next step, also because it has never been tested. The
+mixtures of Pagella and Euler were already replaced by using the upgraded tweak
+mechanism.
+
+That left us with Antykwa, Iwona and Kurier, the fonts that the late Janusz
+Nowacky vectorized and that came with plenty \OPENTYPE\ text fonts but also with
+\TYPEONE\ math companions. And, as we like these fonts, it meant that we had to
+come up with a solution. One option was to create proper \OPENTYPE\ math fonts, but
+another was to strip down the virtual math font mechanism to just support these
+fonts. There is some charm in keeping the \TYPEONE\ fonts, also because it is a
+test case for (by now sort of obsolete) \TFM\ metric, \PFB\ outline, encoding and
+map files, for which we have code embedded so having a proper test case makes
+sense.
+
+In the end we opted for the second solution so this is what the next sections are
+about: supporting \OPENTYPE\ math using \TYPEONE\ fonts. We admit that it took
+way more time than a conversion to \OPENTYPE\ math fonts would have, but that is
+partly due to the fact that these fonts, and especially Antykwa, have some
+characteristic features that we wanted to use. So, in a sense it was also an
+esthetics challenge. It also helped that the font was used in realistic and
+moderately complex math rendering. We also note that rendering in \LMTX\ is
+different (and hopefully better) than in \MKIV\ because we try to benefit from
+the upgraded math engine in \LUAMETATEX.
+
+This exploration is dedicated to Janusz who was one of the characteristic
+presenters of fonts at Bacho\TEX\ meetings, who contributed these fonts, and
+who in some sense was thereby kick starting the Polish \TEX\ related font
+projects.
+
+\stopsubject
+
+\startsubject[title=Virtual math]
+
+We keep this expose simple and only tell what we did, you can look at the \type
+{lfg} files and source code to see what magick is done. For the standard Antykwa
+we load \typ {LatinModern-Math} first, so we cover all symbols that matter. Next
+we stepwise load \typ {rm-anttr.tfm}, \typ {mi-anttri.tfm}, \typ {mi-anttbi.tfm},
+\typ {rm-anttb.tfm}, \typ {sy-anttrz.tfm}, \typ {ex-anttr.tfm}. For each we
+specify an encoding vector. Some are loaded multiple times with different
+vectors. Because we don't like the slanted curly braces we even load \typ
+{AntykwaTorunska-Regular} in order to get the upright ones. This method is not that
+different from what we do in \MKIV.
+
+The specification of a loaded font also can contain a list of (named) characters
+that should be ignored, That was one of the new features in the virtual
+constructor. We take the math parameters from the fonts where these are
+specified, here in the symbols and extension fonts.
+
+The fonts contain extra snippets of extensibles that one can use to construct
+some of these vertical and horizontal stretched symbols on the fly in addition to
+what the font metrics already define. Unfortunately some snippets are missing,
+like the six pieces that could make up horizontal and vertical bars, for which we
+now need to cheat. We considered making a companion font but for now we are in
+\quote {as good as we can} emulation mode.
+
+\stopsubject
+
+\startsubject[title=The fonts]
+
+We start out with a skeleton font and in the past we used the \OPENTYPE\ text
+font for that. On top of that we overlay a bunch of \TYPEONE\ fonts, and as was
+common in those days, the \AMS\ math symbol fonts \type {msa} and \type {msb}
+were overlayed last in order to fill in remaining gaps. However, now that we have
+a Latin Modern \OPENTYPE\ math font it made more sense to use that as starting
+point because it already has all these symbols.
+
+If we forget about the additional weights and condensed variants, the JMN math
+collection has actually not that many fonts. One reason for that is that the
+upright roman font, the ones that have an \type {r} near the end of the file
+name, in traditional \TEX\ speak \type {rm}, have way more than 255 characters:
+it not only has all kind of composed characters, it also has all the extensible
+shapes. All is (as usual with \TYPEONE\ fonts) driven by encoding and mapping
+files. Fortunately the glyphs names (that we use for filtering) are the same for
+the three fonts but there are some more in Antykwa.
+
+\stopsubject
+
+\startsubject[title=Challenges]
+
+The real challenge was Antykwa. This is because it has a distinctive curvature at
+the end of sticky parts (like rules and such). The \TEX\ machinery as well as
+\OPENTYPE\ math assume rules being used in for instance radicals, fractions,
+overbars, underbars and vertical bar fences.
+
+\startlinecorrection
+\scale[width=\textwidth]{\switchtobodyfont[antykwa]\im {
+ \showglyphs
+ \mathbin{-}
+ \mathbin{+}
+ \mathbin{=}
+ \mathbin{<}
+ \mathbin{>}
+}}
+\stoplinecorrection
+
+The last three come in not only sizes (aka variants) but also can stretch (aka
+extensible). And, them being just rules it is assumes that the \TEX\ engine deals
+with that, and as it cannot really do that without characters, the traditional
+approach is to use commands that use \TEX\ rules. However, in \CONTEXT\ (\MKIV\
+and \LMTX) we can provide the proper variants and extensible using virtual
+shapes, and in \LMTX\ we can even scale as last resort.
+
+The first two are special. We already could support fractions using dedicated
+characters because we played with the fraction builder using for instance arrows
+as separator and these are not rules but characters. It was not that much work to
+also make that possible for the rule in a radical. The main adaptation was that
+we need to center the numerator and denominator of a fraction and the body of a
+radical when the character used is wider than requested.
+
+\startlinecorrection
+\scale[height=2cm]{\switchtobodyfont[antykwa]\im {
+ \showglyphs
+ \sqrt{x+1} -
+ \fenced[bar]{
+ \frac{1}{x+1}
+ }
+}}
+\stoplinecorrection
+
+Because we have two font models in \CONTEXT, normal and compact, we had to be careful
+in defining the virtual shapes and extensibles so that they work in both models. This
+has to do with scaling and sharing.
+
+\stopsubject
+
+\startsubject[title=Implementation]
+
+The original virtual math font mechanism worked closely with the math fall back
+features, but these have been replaced by tweaks, which means that we lost some
+of that. Also, heuristics worked fine on the average but for Antykwa we wanted
+more. Therefore some of the built in logic has been moved to the goodie file that
+controls the composition. After all, we don't want to hard code specific
+solutions in the core.
+
+Another addition was the use of so called setups bound to a font class so that we
+can set up some math machinery features for e.g.\ Antykwa in the goodie file. We
+need to bind to a class because we mix a dozen math fonts in one test file and
+therefore we need to separate these setups.
+
+As in regular \OPENTYPE\ math support we ignore the italic correction and translate
+it in combinations of proper width and specific kerning. That way we avoid all kind
+of issues that we otherwise need to compensate for.
+
+Because we need to hook extensible characters into the machine for Antykwa its
+font typescript file also defines a font class specific setup (of a few lines) to
+be applied. This might evolve into a more granular mechanism but for now it works
+fine and adds little overhead.
+
+\stopsubject
+
+\startsubject[title=Examples]
+
+We end by showing a few \quotation{real} examples.
+
+\bgroup\switchtobodyfont[antykwa]
+\startformula
+\binom{n}{k} = \frac{n!}{k!(n-k)!}\mtp{,} 0 \leq k \leq n\mtp{.}
+\stopformula
+\egroup
+
+The parentheses are unchanged, and we believe that using rotation symmetry
+instead of mirror symmetry is a brave but interesting choice, and the new
+fraction bar fits well with it. The fraction bar also fits well with the equal
+sign.
+
+\bgroup
+\switchtobodyfont[antykwa]
+\startformula
+1 + x + x^2 + \ldots + x^n = \frac{1 - x^{n+1}}{1 - x}
+\stopformula
+\egroup
+
+The new vertical bars go well with the brackets, the integral and the solidus.
+
+\bgroup
+\switchtobodyfont[antykwa]
+\startformula
+\fenced[doublebar]{f}_p = \F3\left[ \int_0^1 \fenced[bar]{f(x)}^p \dd x \right]^{1/p}
+\stopformula
+\egroup
+
+The fancy fraction bar and the radical bar have made the arithmetic|-|geometric
+mean inequality look more appealing than ever, hasn't it?
+
+\bgroup
+\switchtobodyfont[antykwa]
+\startformula
+ \frac{a_1 + a_2 + \ldots + a_n}{n} \geq \root[n=n]{a_1 a_2 \ldots a_n}
+\stopformula
+\egroup
+
+Primes are usually a bit of a challenge:
+
+\bgroup
+\switchtobodyfont[antykwa]
+\startformula
+f(k+1)-f(k) \alignhere = f'(k)+f''(k)\frac{1}{2}+f'''(\xi_k)\frac{1}{6}
+ \breakhere = k^p+\frac{p}{2}k^{p-1}+\frac{p(p-1)}{6}\xi_k^{p-2}
+\stopformula
+\egroup
+
+And, as expected, multi|-|line formulas also look fine.
+
+\stopsubject
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-math.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-math.tex
index 83aae8bcd4c..08fabc42661 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-math.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-math.tex
@@ -1089,9 +1089,9 @@ specific classes at the edges. These options are a bitset and \type {1} means
\egroup}
\startcombination[nx=3]
- {\showglyphs\TestSlack{$f^2 > $}} {}
- {\showglyphs\TestSlack{$ > f^^2$}} {}
- {\showglyphs\TestSlack{$f^2 > f^^2$}} {}
+ {\showglyphs\TestSlack{$f^2 > $}} {}
+ {\showglyphs\TestSlack{$ > f^^^2$}} {}
+ {\showglyphs\TestSlack{$f^2 > f^^^2$}} {}
\stopcombination
\stopbuffer
@@ -1127,9 +1127,9 @@ example.
\egroup}
\startcombination[nx=3]
- {\showglyphs\TestSlack{$f^2 > $}} {}
- {\showglyphs\TestSlack{$ > f^^2$}} {}
- {\showglyphs\TestSlack{$f^2 > f^^2$}} {}
+ {\showglyphs\TestSlack{$f^2 > $}} {}
+ {\showglyphs\TestSlack{$ > f^^^2$}} {}
+ {\showglyphs\TestSlack{$f^2 > f^^^2$}} {}
\stopcombination
\stopbuffer
@@ -1992,7 +1992,7 @@ an example of usage:
\setmathspacing \mathexperimentalcode \mathexperimentalcode \allmathstyles 20mu
\setmathspacing \mathordinarycode \mathexperimentalcode \allmathstyles 20mu
-$x^1_2^3_4^^5__6^^7__8$
+$x^1_2^3_4^^^5___6^^^7___8$
\stopbuffer
\typebuffer
@@ -2102,11 +2102,11 @@ habits.
% example:
%
-% $ \left( x + 1 \right )^1_2^^3__4 $
+% $ \left( x + 1 \right )^1_2^^^3___4 $
% \blank
-% $ ( x + 1 )^1_2^^3__4 $
+% $ ( x + 1 )^1_2^^^3___4 $
% \blank
-% $ (^^3__4 x + 1 )^1_2 $
+% $ (^^^3___4 x + 1 )^1_2 $
% example:
%
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-mathfonts.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-mathfonts.tex
new file mode 100644
index 00000000000..98c861d7d6e
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-mathfonts.tex
@@ -0,0 +1,1247 @@
+% language=us runpath=texruns:manuals/ontarget
+
+% musical timestamp: 2022/07/01 while listening to Hania Rani @ https://www.youtube.com/watch?v=sp3B97N67Cw
+
+% todo apply withprescripts -> to all components
+
+\usemodule[math-tweaks]
+
+\startcomponent ontarget-mathfonts
+
+\environment ontarget-style
+
+\startchapter[title={Dealing with math fonts}]
+
+\startsubject[title=Introduction]
+
+Here we will explain some of the tricks that we apply to math fonts so that they
+not only work better with the \LUAMETATEX\ math engine but also look better, at
+least in our opinion. We will not show specific fonts because after all, who can
+complain about something that comes for free, but you can see whatever we do to
+make it work in action in \CONTEXT\ where we setup these fonts. This is also a
+summary of what Mikael Sundqvist and I have been doing for a while now: improve
+the rendering of math, a rather enjoyable experience, also because we ran into
+humorous effects with and properties of fonts. Because we consider ourselves free
+from any conventions we could happily explore solution.
+
+\stopsubject
+
+\startsubject[title=Fences]
+
+\startMPdefinitions
+path My_left_fence ; My_left_fence := (1,1) -- (0,1) -- (0,-1) -- (1,-1) ;
+path My_right_fence ; My_right_fence := (0,1) -- (1,1) -- (1,-1) -- (0,-1) ;
+path My_middle_fence ; My_middle_fence := (0,1) -- (0,-1) ;
+
+path My_right_fence_x ; My_right_fence_x := (0,1) -- (1, 1/2) -- (1,-1/2) -- (0,-1) ;
+
+path My_left_top ; My_left_top := (1, 1 ) -- (0, 1 ) -- (0, 1/2) ;
+path My_left_middle ; My_left_middle := (0, 1/2) -- (0,-1/2) ;
+path My_left_bottom ; My_left_bottom := (0,-1/2) -- (0,-1 ) -- (1,-1 ) ;
+
+path My_right_top ; My_right_top := (0, 1 ) -- (1, 1 ) -- (1, 1/2) ;
+path My_right_middle ; My_right_middle := (1, 1/2) -- (1,-1/2) ;
+path My_right_bottom ; My_right_bottom := (1,-1/2) -- (1,-1 ) -- (0,-1 ) ;
+
+path My_right_top_x ; My_right_top_x := (0, 1 ) -- (1, 1/2) ;
+path My_right_middle_x ; My_right_middle_x := (1, 1/2) -- (1,-1/2) ;
+path My_right_bottom_x ; My_right_bottom_x := (1,-1/2) -- (0,-1 ) ;
+
+path My_middle_top ; My_middle_top := (0, 1 ) -- (0, 1/2) ;
+path My_middle_middle ; My_middle_middle := (0, 1/2) -- (0,-1/2) ;
+path My_middle_bottom ; My_middle_bottom := (0,-1/2) -- (0,-1 ) ;
+
+path My_content ; My_content := fullcircle ;
+
+vardef My_Fenced (expr left, middle, right, size) =
+ image (
+ draw My_left_fence xyscaled (1,left ) shifted (0,0) withcolor darkgray ;
+ draw My_content xyscaled (2,size ) shifted (3,0) withcolor darkblue ;
+ draw My_middle_fence xyscaled (1,middle) shifted (5,0) withcolor darkgray ;
+ draw My_content xyscaled (2,size ) shifted (7,0) withcolor darkblue ;
+ if left <> right :
+ draw My_right_fence_x xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
+ else :
+ draw My_right_fence xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
+ fi ;
+ )
+enddef ;
+
+vardef My_Extensibled (expr left, middle, right, size) =
+ image (
+ draw My_left_top xyscaled (1,left ) shifted (0,0) withcolor darkgray ;
+ draw My_left_middle xyscaled (1,left ) shifted (0,0) withcolor darkgreen ;
+ draw My_left_bottom xyscaled (1,left ) shifted (0,0) withcolor darkgray ;
+ drawpoints My_left_middle xyscaled (1,left ) shifted (0,0) withpen pencircle scaled .4 withcolor white ;
+ drawpoints My_left_top xyscaled (1,left ) shifted (0,0) withpen pencircle scaled .2 withcolor red ;
+ drawpoints My_left_bottom xyscaled (1,left ) shifted (0,0) withpen pencircle scaled .2 withcolor red ;
+ draw My_content xyscaled (2,size ) shifted (3,0) withcolor darkblue ;
+ draw My_middle_top xyscaled (1,middle) shifted (5,0) withcolor darkgray ;
+ draw My_middle_middle xyscaled (1,middle) shifted (5,0) withcolor darkgreen ;
+ draw My_middle_bottom xyscaled (1,middle) shifted (5,0) withcolor darkgray ;
+ drawpoints My_middle_middle xyscaled (1,middle) shifted (5,0) withpen pencircle scaled .4 withcolor white ;
+ drawpoints My_middle_top xyscaled (1,middle) shifted (5,0) withpen pencircle scaled .2 withcolor red ;
+ drawpoints My_middle_bottom xyscaled (1,middle) shifted (5,0) withpen pencircle scaled .2 withcolor red ;
+ draw My_content xyscaled (2,size ) shifted (7,0) withcolor darkblue ;
+ if left <> right :
+ draw My_right_top xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
+ draw My_right_middle xyscaled (1,right ) shifted (9,0) withcolor darkgreen ;
+ draw My_right_bottom xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
+ drawpoints My_right_middle xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .4 withcolor white ;
+ drawpoints My_right_top xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .2 withcolor red ;
+ drawpoints My_right_bottom xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .2 withcolor red ;
+ else :
+ draw My_right_top_x xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
+ draw My_right_middle_x xyscaled (1,right ) shifted (9,0) withcolor darkgreen ;
+ draw My_right_bottom_x xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
+ drawpoints My_right_middle_x xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .4 withcolor white ;
+ drawpoints My_right_top_x xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .2 withcolor red ;
+ drawpoints My_right_bottom_x xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .2 withcolor red ;
+ fi ;
+ )
+enddef ;
+\stopMPdefinitions
+
+Fences come in two variants: fixed sizes and so called extensibles that are
+constructed from recipes that combine snippets that can partially overlap. Fenced
+material has an optional symbol at the start, an optional one at the end and zero
+or more symbols in the middle. Here we have all three:
+
+\startlinecorrection
+\startMPcode
+ draw My_Fenced (2,2,2,2) scaled 5mm ;
+\stopMPcode
+\stoplinecorrection
+
+Ideally these symbols scale in the same way, depending on the other context. This
+means that \TEX\ first has to measure what sits in between but we will not dive
+into that. The left and right symbols are normally pairs like parentheses or
+braces, but any mix is possible. Ideally a font is designed with this in mind but
+unfortunately we see this:
+
+\startlinecorrection
+\startMPcode
+ draw My_Fenced (2,3,2,2) scaled 5mm ;
+\stopMPcode
+\stoplinecorrection
+
+And even this:
+
+\startlinecorrection
+\startMPcode
+ draw My_Fenced (2,3,2.5,2) scaled 5mm ;
+\stopMPcode
+\stoplinecorrection
+
+It might be a side effect of the limited amount fo available slots in traditional
+math fonts that also resulted in non consistent sets in \OPENTYPE\ follow|-|ups
+and when one fonts does that more follow that approach.
+
+You can find rendering like this:
+
+\startlinecorrection
+\startMPcode
+ draw My_Fenced (3,2,3,2) scaled 5mm ;
+\stopMPcode
+\stoplinecorrection
+
+and this
+
+\startlinecorrection
+\startMPcode
+ draw My_Fenced (2,2,2,6) scaled 5mm ;
+\stopMPcode
+\stoplinecorrection
+
+because a programmable language like \TEX\ can use some tricks to force sizes: we
+just create some local fence which dimension is determined by some invisible
+rule. In \LUAMETATEX\ we can actually enforce dimensions and in \CONTEXT\ we can
+filter specific sizes.
+
+So how does this sizing work? A fence character starts out with the normal size
+but then a larger one is needed, the math engine will check if there is a larger
+variant. An \OPENTYPE\ font can provide these and in the engine that works out as
+following a linked list to a next size. When we run out of sizes there can be an
+extension recipe present where a fence is made from snippets pasted together.
+Normally that goes unnoticed because there is a little overlap between these
+snippets.
+
+\startlinecorrection
+\startMPcode
+ draw My_Extensibled (2,2,2,4) scaled 5mm ;
+\stopMPcode
+\stoplinecorrection
+
+A larger fence will simply add more middle pieces, and it will not do as below:
+
+\startlinecorrection
+\startMPcode
+ draw My_Extensibled (3,3,3,6) scaled 5mm ;
+\stopMPcode
+\stoplinecorrection
+
+Because we're talking of a deliberate design you cannot simply scale snippets and
+expect them to work out well visually. However, in a pure vertical case one
+actually could and in practice all these extensibles have (of course) vertical
+bars. Anyway, in the above example the larger middle piece actually is just
+several middle pieces overlapping.
+
+However, as we mentioned, fonts are not always consistent. First of all, when we
+run over the (increasing in size) variants we have discrete steps and you're
+lucky if a font has more than half a dozen. As soon as we end up with the
+extensible the size can be matched well.
+
+So how do we compensate for misbehavior? There are two parameters in \TEX\ then
+determine the matching: \typ {\delimiterfactor} and \typ {\delimitershortfall}.
+Plain \TEX\ set them to 901 and 5pt which works okay in most cases. In \CONTEXT\
+we set them to 1000 and 0pt and instead use the parameters \typ
+{\UmathDelimiterPercent} and \typ {\UmathDelimiterShortfall} that are bound fo
+fonts. In addition to that we use the \typ {nooverflow} keyword with \type
+{\Umiddle} which makes sure that we always stay within the size of the outer
+fences. That just looks better.
+
+In addition we can tweak the dimensions of glyphs and apply effects such as
+expanding so that we get a bit more consistent visual appearance. We can also
+signal that we should ignore sizes larger than a given index.
+
+The next sequence show what happens in practice when we tell \type {\Umiddle} to
+never exceed the requested size. Because we start with stepwise sizes the first
+part of this sequence has no matching sizes. At some point we end up at the
+extensibles.
+
+\showmathmiddletweaks
+
+Its is worth noticing that we tried several alternative approaches. For instance
+what happens when we only use extensibles? In that case there will be no fit for
+the smaller ones because the at least two parts of an extensible can seldom
+completely overlap that much.
+
+Actually, when we tested that we noticed that even in valid situations there can
+be strange overlap. At that time for instance the Lucida fonts had overlapping
+artifact in some curly braces which we found out when we tried to nil some of the
+larger, odd looking, step variants. Latin modern and some of the gyre fonts had
+unexpected jumps to larger sizes which made us decide to make the delimiter
+parameters font specific so that we could more easily adapt them: they basically
+became part of the math parameters of a font.
+
+There are also inconsistencies in the perceived widths of glyphs used: often the
+bars are too thin. That can be solved by applying effects like scaling
+horizontally or vertically and cheating a bit with the dimensions. Another
+solution is that we ignore the variants after a certain size and force
+extensibles sooner but that of course needs to be tested for unwanted overlaps
+too. All these tricks combined make it possible to use math fonts with imperfect
+fences more or less reliable.
+
+\startitemize[packed]
+\startitem
+ Provide an equal amount of fixed size larger variants for all fences: assume
+ arbitrary pairing.
+\stopitem
+\startitem
+ Because fonts have plenty room, provide some ten variants before going
+ extensible.
+\stopitem
+\startitem
+ Try to make the variants and the extensibles similar in look.
+\stopitem
+\startitem
+ Ensure that the width of the vertical bar matches the design.
+\stopitem
+\startitem
+ Make sure that the odd entries in a extensible recipe don't overlap badly.
+\stopitem
+\stopitemize
+
+\stopsubject
+
+\startsubject[title=Accents]
+
+When traditional \TEX\ showed up it was not that common to have pre|-|composed
+characters so when you needed something with an accept on top the way to go was
+to typeset the base character and position the accent on top using either the
+\type {\accent} primitive or some macro. It always was a compromise but
+eventually fonts with more assembled characters showed up. In \OPENTYPE\ fonts
+that operate in the \UNICODE\ domain we have even more characters but even there
+characters can be composed. However, anchors that help achieving this are part of
+the format. For text we use the mark features and for math we use the top anchor.
+Given that, why do we need to tweak it?
+
+\startMPdefinitions
+path My_top_accent ; My_top_accent := (-1/2,0) -- (0,1/4) -- (1/2,0) ;
+
+path My_content ; My_content := fulldiamond ;
+
+vardef My_Accent (expr shift, accent, size, slant) =
+ image (
+ path p ; p := My_content
+ xyscaled (2,size)
+ slanted slant
+ ;
+ draw My_top_accent
+ xyscaled (1,accent)
+ shifted (0,2)
+ withcolor darkgray ;
+ draw p
+ withcolor darkblue ;
+ )
+enddef ;
+
+vardef My_Accent_X (expr shift, accent, size, slant, rotation) =
+ image (
+ path p ; p := My_content rotated rotation
+ xyscaled (2,size)
+ slanted slant
+ ;
+ draw My_top_accent
+ xyscaled (1,accent)
+ shifted point 2 of p
+ shifted - (0,-1)
+ withcolor darkgray ;
+ draw p
+ withcolor darkblue ;
+ )
+enddef ;
+
+vardef My_Accent_Y (expr shift, accent, size, scale) =
+ image (
+ path p ; p := My_content
+ xyscaled (2,size)
+ ;
+ draw My_top_accent xscaled scale
+ xyscaled (1,accent)
+ shifted (0,2)
+ withcolor darkgray ;
+ draw p
+ withcolor darkblue ;
+ )
+enddef ;
+
+vardef My_Accent_Z (expr shift, accent, size, scale) =
+ image (
+ path p ; p := My_content
+ xyscaled (2,size)
+ ;
+ path q ; q := My_top_accent
+ xscaled scale
+ xyscaled (1,accent)
+ shifted (0,2)
+ ;
+ draw q
+ withcolor darkgray ;
+ draw p
+ withcolor darkblue ;
+ draw outerboundingbox q
+ withpen pencircle scaled 1/20
+ withcolor darkred ;
+ draw outerboundingbox p
+ withpen pencircle scaled 1/20
+ withcolor darkred ;
+ )
+enddef ;
+\stopMPdefinitions
+
+Here we have a base character with an accent on top. The character is upright and
+the accent gets positioned in the middle.
+
+\startlinecorrection
+\startMPcode
+ draw My_Accent (2.5,1,2,0) scaled 5mm ;
+\stopMPcode
+\stoplinecorrection
+
+This doesn't work out well if we have a slanted or italic shape:
+
+\startlinecorrection
+\startMPcode
+ draw My_Accent (2.5,1,2,.2) scaled 5mm ;
+ draw My_Accent (2.5,1,2,.4) scaled 5mm shifted (2cm,0) ;
+ draw My_Accent (2.5,1,2,.6) scaled 5mm shifted (4cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+So we need to compensate, for instance like this:
+
+\startlinecorrection
+\startMPcode
+ draw My_Accent_X (2.5,1,2,.2,0) scaled 5mm ;
+ draw My_Accent_X (2.5,1,2,.4,0) scaled 5mm shifted (2cm,0) ;
+ draw My_Accent_X (2.5,1,2,.6,0) scaled 5mm shifted (4cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+However, what does determine the right anchor point? From this example you can
+conclude that it is the top of the character. It is probably for that reason why
+the semi automated construction of Latin Modern and the Gyre fonts have quite
+some anchors that are rather bad: getting the anchors right is more a visual job
+than something that can be automated. The topmost point is not really the best
+one to focus on.
+
+\startlinecorrection
+\startMPcode
+ draw My_Accent_X (2.5,1,2,.2,35) scaled 5mm ;
+ draw My_Accent_X (2.5,1,2,.4,35) scaled 5mm shifted (2cm,0) ;
+ draw My_Accent_X (2.5,1,2,.6,35) scaled 5mm shifted (4cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+Here the topmost position is very off center. In for instance Latin Modern that
+means that on digits like~7 and~4 you get very weird anchoring. And this is why
+we have a tweak that just wipes all the anchors from an alphabet: most alphabets
+don't need them anyway and the engine will use the center when no anchor is
+defined. Just for the record: in traditional \TEX\ engines the horizontal
+position is determined by the kern between a so called skew character and the
+base character. The font format has no anchor field but it has kerns, so this
+trick makes much sense.
+
+We discussed vertical extensible that grow but horizontally we have accents that
+can grow. There are also a few horizontal fences like braces that have
+extensibles but we will cover that later. Accents are such that they only have a
+fixed set of variants and one problem is that there are often not enough of them.
+This means that the engine has to choose one that is reasonable.
+
+\startlinecorrection
+\startMPcode
+ draw My_Accent_Y (2.5,1,2,1) scaled 5mm ;
+ draw My_Accent_Y (2.5,1,2,2) scaled 5mm shifted (2cm,0) ;
+ draw My_Accent_Y (2.5,1,2,2.5) scaled 5mm shifted (4cm,0) ;
+ draw My_Accent_Y (2.5,1,2,3) scaled 5mm shifted (6cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+In the example above the first two are acceptable but the third and fourth are
+not. Just imagine that there is a superscript or subscript involved. Here we
+apply another cheat: we lie about the dimensions. A glyph can have left and right
+margins that get subtracted when the accent analyzer tries to make a fit which
+means that we can sort of enforce the second solution. The \CONTEXT\ font goodie
+files set the margins for some problematic characters because (of course) these
+are not part of \OPENTYPE\ math fonts. This is an optical issue mostly because the
+engine will not easily put a too wide one on top.
+
+\startlinecorrection
+\startMPcode
+ draw My_Accent_Z (2.5,1.0,2,1) scaled 5mm ;
+ draw My_Accent_Z (2.5,1.5,2,2) scaled 5mm shifted ( 2cm,0) ;
+ draw My_Accent_Z (2.5,2.0,2,3) scaled 5mm shifted ( 4cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+Watch how the larger accents also have a larger bounding box. That is all right
+but does interfere with a consistent makeup. The solution is simple: we use the
+\CONTEXT\ dimension tweak to reposition accents and cheat with their height and
+depth to make sure that we get consistent rendering. We need to tweak anyway
+because sometimes accents have bad dimensions. The smallest one is actually a
+text accent and therefore can have properties that are inconsistent with its
+wider variants. This is typically a side effect of the fact that math accents and
+text accents are not considered to be different.
+
+\startitemize[packed]
+\startitem
+ Only add anchors to some (forward leaning!) italic shapes.
+\stopitem
+\startitem
+ Make extensibles as much a possible consistent with respect to dimensions.
+\stopitem
+\stopitemize
+
+\stopsubject
+
+\startsubject[title=Kerning]
+
+In a text font there are two mechanisms that influence the spacing between
+individual characters: kerning and italic corrections. In \OPENTYPE\ text fonts
+we have a more generalized relative positioning mechanism which can be seen as
+kerning. The italic correction well known to \TEX\ users can be implemented as a
+positional font feature but very seldom is.
+
+An \OPENTYPE\ math font has both kerning and italic correction. The kerning at
+the left top, left bottom, right top and right bottom of a glyph can be specified
+as a staircase and is used to position scripts. The italic correction is bit more
+curious and is applied is some cases. Keep in mind that in math a sequence of
+alphabetic characters does not make a word but represents a multiplication of
+ordinary symbols and thereby specific inter|-|atom spacing rules apply.
+
+A traditional \TEX\ font has kerns and italic correction and an \OPENTYPE\ font has
+staircase kerns and italic correction. For practical (space and time) reasons the
+widths of italic shapes in traditional math fonts are such that when you add the
+correction they kind of match the bounding box.
+
+So, one way to suit both kind of fonts is to add the italic correction (often
+absent in \OPENTYPE\ glyphs but very present in traditional ones) as well as the
+staircase kerns (present in \OPENTYPE\ fonts and unknown to traditional fonts).
+
+There are however some complications: what if a glyph has both? Which one is to
+be preferred? Should we try our luck? Even worse: in the traditional the italic
+correction is {\em always} added to the box that wraps a glyph but in some cases
+that correction gets removed. \footnote {In \LUAMETATEX\ we never remove but
+compensate so that we can track what happens.} But should we also remove a
+staircase kern? When we started with \LUAMETATEX\ it was a bit of a gamble
+because the specification only showed up later and improved over time. \footnote
+{This is true for much of \OPENTYPE\ which has the danger that bugs and side
+effects become features. Keep that in mind when you criticize solutions that
+early adopters came up with!}
+
+In \LUATEX\ we often have to code paths. That was done after other attempts to
+deal with this weak aspect of fonts worked for one font and not for the other.
+For instance at the time of this writing some fonts have italic corrections for
+upright characters! In \LUAMETATEX\ that model was changed into a detailed
+control model at the font as well as engine level. Later, when Mikael and I went
+over the fonts, usage of characters in math, atoms and spacing, we decided to
+kick out that detailed control and use more general control mechanisms assuming
+that we use \OPENTYPE\ fonts without bad italics. Whenever we had bad ones we
+could correct that in a so called font goodie file. In other words: no heuristics
+in the engine but fixed fonts. For that we always take Cambria as reference.
+
+{\em To be considered: should we finally turn italic correction into top and
+bottom kerns? Basically: model after Cambria? Then we can kick out code! We just
+assume font goodies.}
+
+\startMPdefinitions
+vardef My_Character (expr shape, sx, sy, slant, left, right, side) =
+ image (
+ path p ; p := shape
+ xyscaled (sx, sy)
+ slanted slant
+ ;
+ draw p
+ withcolor darkgray ;
+ draw (outerboundingbox p) leftenlarged side rightenlarged side
+ withpen pencircle scaled 1/20
+ withcolor darkgreen ;
+ draw (outerboundingbox p) leftenlarged left rightenlarged right
+ withpen pencircle scaled 1/20
+ withcolor darkred ;
+ )
+enddef ;
+
+vardef My_Character_K (expr shape, sx, sy, slant, left, right, lt, lb, rt, rb) =
+ image (
+ path p ; p := shape
+ xyscaled (sx, sy)
+ slanted slant
+ ;
+ draw p
+ withcolor darkgray ;
+ draw (outerboundingbox p) leftenlarged left rightenlarged right
+ withpen pencircle scaled 1/20
+ withcolor darkred ;
+ draw (ulcorner outerboundingbox p) shifted (lt,0)
+ withpen pencircle scaled 1/2
+ withcolor darkgreen ;
+ draw (llcorner outerboundingbox p) shifted (lb,0)
+ withpen pencircle scaled 1/2
+ withcolor darkgreen ;
+ draw (urcorner outerboundingbox p) shifted (rt,0)
+ withpen pencircle scaled 1/2
+ withcolor darkgreen ;
+ draw (lrcorner outerboundingbox p) shifted (rb,0)
+ withpen pencircle scaled 1/2
+ withcolor darkgreen ;
+ )
+enddef ;
+\stopMPdefinitions
+
+\startlinecorrection
+\startMPcode
+ draw My_Character (fulldiamond, 2, 4, 0, 1/4, 1/4, 0) scaled 5mm ;
+ draw My_Character (fullcircle, 2, 4, 0, 1/4, 1/4, 0) scaled 5mm shifted (3cm,0) ;
+ draw My_Character (fullsquare, 2, 4, 0, 1/4, 1/4, 0) scaled 5mm shifted (6cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+Here we have three shapes and as usual they have some space at the left and right.
+A text font like Lucida is designed in such a way that no kerns between glyphs
+are needed but most text fonts have kerns. These compensate for these average
+acceptable side bearings.
+
+\startlinecorrection
+\startMPcode
+ draw My_Character (fulldiamond, 2, 4, 0.3, 1/4, 1/4, 0) scaled 5mm ;
+ draw My_Character (fullcircle, 2, 4, 0.3, 1/4, 1/4, 0) scaled 5mm shifted (3cm,0) ;
+ draw My_Character (fullsquare, 2, 4, 0.3, 1/4, 1/4, 0) scaled 5mm shifted (6cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+In these slanted versions we get wider shapes but not always. For some shapes the
+amount of perceived spacing at the left top and right bottom increases and this is
+where we start thinking in terms of italic correction:
+
+\startlinecorrection
+\startMPcode
+ draw My_Character (fulldiamond, 2, 4, 0.3, 1/4, 1/4, 0 ) scaled 5mm ;
+ draw My_Character (fullcircle, 2, 4, 0.3, 1/4, 1/4, 0 ) scaled 5mm shifted (3cm,0) ;
+ draw My_Character (fullsquare, 2, 4, 0.3, 1/4, -1/2, 1/4) scaled 5mm shifted (6cm,0) ;
+ draw My_Character (fullsquare, 2, 4, 0.3, -1/2, -1/2, 1/4) scaled 5mm shifted (9cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+That way, when we put characters next to each other on the average words look
+better. But how about math: a superscript should be outside that bounding box and
+a subscript inside, assuming that we have a shape like this. It is unfortunate
+that the widely used $f$ is the perfect candidate. When using that one as test
+case things can look great but kick in a $g$ and it gets worse. The $v$ and $w$
+are also a fertile playground. It is hard to come up with logic that satisfied
+all which is why glyph specific engine control was implemented (and later
+dropped). In the previous graphic the fourth shape also cheats on the left and
+yes, there are some fonts that do just that, which the of course interferes with
+prescripts.
+
+Now think of using shapes in formulas: some are put in sequence, in which case
+inter atom spacing is added so there is less danger of touching due to too a
+narrow width and \TEX ies somehow accepted that adding thin spaces every now and
+then is fine \footnote {We don't think so which is why we came up with a more
+granular inter atom spacing mode.} But there's more than sequences: shapes end up
+in scripts, as degrees in radicals, above and below fraction rules, as fences and
+accents. Just assume the worst possible scenarios!
+
+In these examples the italic correction at the right is the difference between
+the red and green box. There is no left italic correction and that is why \OPENTYPE\
+math (driven by Cambria) has these four sets of kerns.
+
+\startlinecorrection
+\startMPcode
+ draw My_Character_K (fulldiamond, 2, 4, 0.3, 1/4, 1/4, 1/4, -1/4, 1/2, -1/4) scaled 5mm ;
+ draw My_Character_K (fullcircle, 2, 4, 0.3, 1/4, 1/4, 1/8, 0, 0, -1/8) scaled 5mm shifted (3cm,0) ;
+ draw My_Character_K (fullsquare, 2, 4, 0.3, 1/4, 1/4, 1/8, -1/2, 1/2, -1/8) scaled 5mm shifted (6cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+Here we show some possibilities for better anchoring but it will be clear that it
+is a compromise. Staircase kerns as in \OPENTYPE\ therefore have a set of kerns
+going up or down for not only the base character but also the one that ends up in
+a script as that one itself can have a \quote {problematic} shape.
+
+Our solution to this problem is to tweak dimensions and italic correction of
+problematic characters. We also can add four kerns that roughly compensate for
+tricky corrections needed. We therefore have more glyph properties than the
+official \OPENTYPE\ specification provides (cheaper and easier than staircase
+kerns that work on pairs of characters) . But we have more font parameters
+anyway, and with \TEX\ being one of the main math renderers and \TEX ies always
+being to tune and tweak we think this is okay. It is better to have more control
+than to rely on (hard to fight) heuristics.
+
+We're stuck with the fonts we have and (in the case of \TEX\ fonts) the chosen
+traditional approach of dimensions and italic corrections (no staircase kerns) but
+the least we can ask is:
+
+\startitemize[packed]
+ \startitem
+ Be consistent in dimensions and italic corrections. Get rid of limitations
+ imposed by the 8 bit font era: we have plenty slots available and some more
+ glyph properties as well. And if you compromise: make that clear.
+ \stopitem
+ \startitem
+ Don't just take the old properties but assume that \OPENTYPE\ math fonts
+ are used in a modern \OPENTYPE\ \TEX\ engine.
+ \stopitem
+ \startitem
+ Assume that any character is used in any combination: that is what made it
+ hard to satisfy all needs at the engine end. Better play safe.
+ \stopitem
+\stopitemize
+
+\stopsubject
+
+\startsubject[title=Scripts and primes]
+
+We start with showing a few shapes (in \TEX\ speak: nuclei) with a different
+perceived spacing and with some items attached to the corners: scripts.
+
+\startMPdefinitions
+vardef My_Character_P (expr shape, sx, sy, slant, left, right, prime, index) =
+ image (
+ path p ; p := shape
+ xyscaled (sx, sy)
+ slanted slant
+ ;
+ draw p
+ withcolor darkgray ;
+ draw (outerboundingbox p) leftenlarged left rightenlarged right
+ withpen pencircle scaled 1/20
+ withcolor darkred ;
+ draw (fullsquare shifted (ulcorner outerboundingbox p)) shifted (-1,0)
+ withpen pencircle scaled 1/5
+ withcolor darkgreen ;
+ draw (fullsquare shifted (llcorner outerboundingbox p)) shifted (-1,0)
+ withpen pencircle scaled 1/5
+ withcolor darkgreen ;
+ if prime:
+ draw (fullsquare xyscaled(1/2,1) shifted (urcorner outerboundingbox p)) shifted (.75,1/2)
+ withpen pencircle scaled 1/5
+ withcolor darkblue ;
+ draw (fullsquare shifted (urcorner outerboundingbox p)) shifted (1.75,0)
+ withpen pencircle scaled 1/5
+ withcolor darkgreen ;
+ else :
+ draw (fullsquare shifted (urcorner outerboundingbox p)) shifted ( 1,0)
+ withpen pencircle scaled 1/5
+ withcolor darkgreen ;
+ fi
+ if index:
+ draw (fullsquare shifted (lrcorner outerboundingbox p)) shifted (if prime: 3 else : 2 fi,0)
+ withpen pencircle scaled 1/5
+ withcolor darkyellow ;
+ else :
+ draw (fullsquare shifted (lrcorner outerboundingbox p)) shifted ( 1,0)
+ withpen pencircle scaled 1/5
+ withcolor darkgreen ;
+ fi ;
+ )
+enddef ;
+\stopMPdefinitions
+
+\startlinecorrection
+\startMPcode
+ draw My_Character_P (fulldiamond, 2, 4, 0, 1/4, 1/4, false, false) scaled 5mm ;
+ draw My_Character_P (fullcircle, 2, 4, 0, 1/4, 1/4, false, false) scaled 5mm shifted ( 5cm,0) ;
+ draw My_Character_P (fullsquare, 2, 4, 0, 1/4, 1/4, false, false) scaled 5mm shifted (10cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+The green ones represent the super- and sub-, pre- and postscripts. According to what we
+discussed previously the anchoring depends on the shape
+
+\startlinecorrection
+\startMPcode
+ draw My_Character_P (fulldiamond, 2, 4, .3, 1/4, 1/4, false, false) scaled 5mm ;
+ draw My_Character_P (fullcircle, 2, 4, .3, 1/4, 1/4, false, false) scaled 5mm shifted ( 5cm,0) ;
+ draw My_Character_P (fullsquare, 2, 4, .3, 1/4, 1/4, false, false) scaled 5mm shifted (10cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+But we will not take that into account here because this time we focus on support
+for primes and indices. A prime normally is a narrow character that is positioned
+after the nuclues and sits in a similar position as a superscript. When it is
+present a subscript doesn't move. Here the blue rectangle represents the prime.
+
+\startlinecorrection
+\startMPcode
+ draw My_Character_P (fulldiamond, 2, 4, 0, 1/4, 1/4, true, false) scaled 5mm ;
+ draw My_Character_P (fullcircle, 2, 4, 0, 1/4, 1/4, true, false) scaled 5mm shifted ( 5cm,0) ;
+ draw My_Character_P (fullsquare, 2, 4, 0, 1/4, 1/4, true, false) scaled 5mm shifted (10cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+An index, here yellow, is a subscript that applies to the whole so that one does
+move. We cannot have a subscript and an index at the same time. The prescripts
+are not affected by primes and indices other than that the engine has to do more
+work in getting it right.
+
+\startlinecorrection
+\startMPcode
+ draw My_Character_P (fulldiamond, 2, 4, 0, 1/4, 1/4, false, true) scaled 5mm ;
+ draw My_Character_P (fullcircle, 2, 4, 0, 1/4, 1/4, false, true) scaled 5mm shifted ( 5cm,0) ;
+ draw My_Character_P (fullsquare, 2, 4, 0, 1/4, 1/4, false, true) scaled 5mm shifted (10cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+Of course we can have primes and indices at the same time. A prime actually belongs to the
+nuclues so that combination determines quite a bit of the vertical and horizontal spacing.
+
+\startlinecorrection
+\startMPcode
+ draw My_Character_P (fulldiamond, 2, 4, 0, 1/4, 1/4, true, true) scaled 5mm ;
+ draw My_Character_P (fullcircle, 2, 4, 0, 1/4, 1/4, true, true) scaled 5mm shifted ( 5cm,0) ;
+ draw My_Character_P (fullsquare, 2, 4, 0, 1/4, 1/4, true, true) scaled 5mm shifted (10cm,0) ;
+\stopMPcode
+\stoplinecorrection
+
+The problem with primes is that they were never part of the concept and
+\OPENTYPE\ math inherited that. Thanks to \UNICODE\ (and the math community not
+being convincing enough) we ended up with a prime being equivalent to minutes and
+double primes being minutes. The fact that we have triple and quadruple primes as
+well as reverse primes is a consequence of not having symbols for sub second
+indicators. And even the seconds are overloaded by meaning: time related and
+geographical.
+
+What has this to do with primes? Well, it means that a font has a prime character
+that is already positioned at a certain distance from the baseline. But in most
+math fonts the script and scriptscript sizes aren't. It looks as if the
+assumption is that primes are treated like superscripts. But which one then gets
+superscripted at the text level? The text one or the script one? Unfortunately
+fonts are somewhat inconsistent in the sizing and positioning of primes and the
+math community not being convincing enough. It was a tough decision to make: in
+some fonts using the text prime have nice output and in other fonts the script
+one.
+
+So, because in the traditional approach primes had to be manually positioned, be
+able deal with super and subscripts the old school approach was to make them
+active characters and pick up what follows in order to deal with this situation.
+It probably is the main reason why we have a somewhat special active character
+mechanism in math mode. In \CONTEXT\ \MKIV\ we followed a different approach,
+also because we wanted to deal with collapsing multiple primes to their rightful
+\UNICODE\ slot.
+
+In \LMTX\ and \LUAMETATEX\ we (need to) go a step further because we want proper
+inter|-|atom space as well as more fine tuned positioning. Primes became elements
+bound to a nucleus! We also wanted to solve this issue once and for all (in
+\MKIV\ we has several methods but in \LMTX\ we only have one left). We not only
+added a native prime element to nuclei but also introduced font parameters
+similar to those of superscripts. Just keep in mind that in \LUAMETATEX\ we don't
+need to worry about having a few more fields in a math node. There are not that
+many nodes involved and the amount of extra memory used can be neglected. Of
+course there is plenty of code added to deal with it so the binary definitely is
+larger due to it and the code way more complex. In fact we already introduced
+some missing parameters for the spacing related to prescripts. Furthermore we can
+tune the prime spacing relative to the scripts.
+
+In the goodie files you can add fixes that relate to primes and most of them
+involved quite a bit of experimental. We can safely say that we spent quite some
+prime time on this issue.
+
+\startitemize[packed]
+\startitem
+ It would be nice if fonts at least has prime shapes that are consistent
+ because currently script one can look quite different (tilt and shape).
+\stopitem
+\startitem
+ Because primes are also minutes and seconds we probably have to accept the
+ current situation and deal with it in the goodie files forever.
+\stopitem
+\stopitemize
+
+\stopsubject
+
+% Yet another section, this time I got in the mood after listening to Cindy
+% Blackman Santana’s "Give The Drummer Some" ... here we go:
+
+\startsubject[title=Two choices]
+
+Imagine a situation like this: a sequence of characters with a leading left fence
+but nothing at the right. The fence is not really a fence but something that can
+grow and have its own super and subscripts, either after it or on top and below.
+We leave these scripts (aka limits) out of the discussion.
+
+\startMPdefinitions
+vardef My_Character (expr shape, sx, sy, c) =
+ image (
+ draw
+ shape xyscaled (sx, sy)
+ withcolor c ;
+ )
+enddef ;
+\stopMPdefinitions
+
+\startlinecorrection
+\startMPcode
+ draw My_Character (fulldiamond, 2, 4, darkblue) scaled 5mm ;
+ for i = 1 upto 5 :
+ draw My_Character (fullcircle, 2, 2 randomized 1, darkgray ) scaled 5mm shifted (i * 2cm,0) ;
+ endfor ;
+\stopMPcode
+\stoplinecorrection
+
+There is a visual aspect here, which can be illustrated from a variant:
+
+\startlinecorrection
+\startMPcode
+ draw My_Character (fulldiamond, 2, 4, darkblue) scaled 5mm ;
+ for i = 1 upto 3 :
+ draw My_Character (fullcircle, 2, 2 randomized 1, darkgray ) scaled 5mm shifted (i * 2cm,0) ;
+ endfor ;
+ draw My_Character (fulldiamond, 2, 6, darkblue) scaled 5mm shifted (9cm,0) ;
+ for i = 1 upto 3 :
+ draw My_Character (fullcircle, 2, 3 randomized 1, darkgray ) scaled 5mm shifted (9cm + i * 2cm,0) ;
+ endfor ;
+\stopMPcode
+\stoplinecorrection
+
+One can argue that the larger characters in the second sequence rightfully trigger a larger
+blue variant. But for consistency one might actually go for:
+
+\startlinecorrection
+\startMPcode
+ draw My_Character (fulldiamond, 2, 6, darkblue) scaled 5mm ;
+ for i = 1 upto 3 :
+ draw My_Character (fullcircle, 2, 2 randomized 1, darkgray ) scaled 5mm shifted (i * 2cm,0) ;
+ endfor ;
+ draw My_Character (fulldiamond, 2, 6, darkblue) scaled 5mm shifted (9cm,0) ;
+ for i = 1 upto 3 :
+ draw My_Character (fullcircle, 2, 3 randomized 1, darkgray ) scaled 5mm shifted (9cm + i * 2cm,0) ;
+ endfor ;
+\stopMPcode
+\stoplinecorrection
+
+Now imagine that you only have two choices? When do you go for the larger one?
+This situation occurs with so called large operators like integrals and
+summations. The original \TEX\ fonts have two sizes of these characters. The
+smaller one is used in normal (text) math and the larger one in display math.
+
+But what if, as in \OPENTYPE\ fonts there are more? There is a font parameter \typ
+{DisplayOperatorMinHeight} that tells what size to use (as a minimum) in display
+mode. Because the \TEX\ engines never had to make a decision the value of that
+variable in the Latin Modern and Gyre fonts is somewhat arbitrary. It is one of
+the variables that we need to adapt in the goodie files: we roughly bump from
+1300 to 1800 to get what we are accustomed to in display mode.
+
+So what are these large operators anyway? In traditional \TEX\ they are just
+that: larger variants of smaller ones. In \OPENTYPE\ math however, they are
+extensibles. That means that when there are more variants and an extensible
+recipe it can grow on demand. That conflicts with the expectations of two sizes.
+
+In order to support these two conflicting demands \LUAMETATEX\ provides so called
+left operators that either act upon their own, in which case we talk of \quote
+{auto} mode, or they can be told to have a specific size, or they can adapt, in
+which case they have the usual bogus right companion that ends the subformula.
+And, because they are implemented as fences but are not really fences there are
+some provisions for the scripts: they bind to the left fence and not the right
+one.
+
+As side note: when we were experimenting with the usage of these (new) mechanisms
+we again ran into the race condition that is imposed by the algorithm that
+determines the size of fences: the delimiters target height is either a fraction
+of the total height of the sublist or the total height diminished by some
+constant amount. In \LUAMETATEX\ we therefore added the already discussed \typ
+{\UmathDelimiterPercent} and \typ {\UmathDelimiterShortfall} but these only kick
+in when we have a wrapped integral or such.
+
+\startitemize[packed]
+\startitem
+ We can't be too picky but it would be nice if fonts have \typ
+ {DisplayOperatorMinHeight} set to a more reasonable value. We have to tweak
+ most font for this now (and probably forever).
+\stopitem
+\stopitemize
+
+\stopsubject
+
+\startsubject[title=To the point]
+
+A nice feature of math fonts is that they have so called extensible characters. Fences
+can grow vertically and accents horizontally. When we run out of discrete steps in size,
+we end up with a recipe that build large characters from snippets as we discussed before.
+
+The limitations in the size of fonts and the fact that the engine also had to
+impose some limits in the amount of used fonts and complexity of their usage made
+for some exceptions to the rule and, no pun intended, it might be why \TEX\ has a
+concept of rules. Lines over and under something, arrows, fractions and radicals
+all use rules. It is interesting to notice that when \OPENTYPE\ fonts showed up
+the converted \TEX\ fonts didn't make arrows and bars use the extension
+mechanism, thereby forcing the old school construction of them. This doesn't hurt
+\CONTEXT\ much because we can implement proper characters using the virtual
+character mechanism and we did things different anyway (for instance we can kick
+in \METAFUN\ replacements).
+
+Nevertheless there is this curious in|-|between: radical. It comes in a set of
+fixed sized often sloped characters and then switches to an upright one. In all
+cases there is that horizontal rule attached that covers the nucleus. There is no
+mix of horizontal and vertical extensibles so there is no fancy end of rule
+thingie possible (the little hook that we learned to draw at school): it's just a
+stupid rule.
+
+\startlinecorrection
+\startMPcode
+ for i = 1 upto 5 :
+ draw image (
+ draw fullsquare xyscaled(2, 4+i)
+ withcolor darkblue ;
+ fill fullsquare xyscaled(1/2, 1/2+i)
+ shifted (1,2)
+ withcolor darkblue ;
+ draw fullsquare xyscaled(1, 1)
+ shifted (1+i/100,2+i/2+i/100)
+ withcolor darkgray ;
+ ) scaled 5mm shifted (i*2cm, 0) ;
+ endfor ;
+\stopMPcode
+\stoplinecorrection
+
+Instead of a rule, these examples show a simple rectangle attached to another
+one. The idea is that the center of that small one snaps onto the upper right
+corner of the large one. In these examples we show how it looks when that is not
+exact. At small sizes it goes unnoticed but at larger ones it becomes visible.
+Actually, when you start scaling up math you often see artifacts in shapes, which
+makes one wonder if high resolution screens are really used for proofing.
+
+\startlinecorrection
+\startMPcode
+ for i = 1 upto 5 :
+ draw image (
+ draw fullsquare xyscaled(2, 4+i)
+ withcolor darkblue ;
+ draw fullsquare xyscaled(1, 1)
+ shifted (1+i/100,2+i/2+i/100)
+ withcolor darkgray ;
+ ) scaled 5mm shifted (i*2cm, 0) ;
+ endfor ;
+\stopMPcode
+\stoplinecorrection
+
+In the first example the effect is small because we make sure that the right top
+corner is square but in the second one we don't do that. Now it really becomes
+annoying, even if we remove the small errors in positioning.
+
+\startlinecorrection
+\startMPcode
+ for i = 1 upto 5 :
+ draw image (
+ draw fullsquare xyscaled(2, 4+i)
+ withcolor darkblue ;
+ draw fullsquare xyscaled(1, 1)
+ shifted (1,2+i/2)
+ withcolor darkgray ;
+ ) scaled 5mm shifted (i*2cm, 0) ;
+ endfor ;
+\stopMPcode
+\stoplinecorrection
+
+We have seen different effects. The most common was an inaccurate font dimension
+that determines what the height of the rule is. That we can fix in the goodie
+file and we do that. Other artifacts were (in the stepwise sizes) characters that
+were so sloped that there was not possibility for properly attaching the rule (we
+noticed this best when checking the Lucida and Latin Modern fonts): one can cheat
+and move a little to the left but the thickness of the sloped line was not enough
+for that, so it could qualify as a design error but a design cannot simply be
+changed in such case: one has to compromise and assume no scaling (keep in mind
+that we scale on screen while on print one has to take a magnifying glass and
+reading math that way is not much fun).
+
+Some of these extensible radicals have rather thin vertical lines but we can
+assume that their height is never such that this becomes too annoying. One
+complication in designing these shapes is that when one uses a font creator
+program it is unlikely to provide a math composer for testing. The same is true
+for overlapping the end glyphs of e.g.\ curly braces: the middle piece can get
+into the way when we have the smallest extensible and have that one kick in too
+soon due to the lack of stepwise sizes. It's hard to check that without an engine
+applying them to the extreme cases.
+
+\startitemize[packed]
+\startitem
+ Benefit from your high resolution screen and zoom in on the results. Take no
+ risk.
+\stopitem
+\startitem
+ Play safe and create an top right corner that has some overlap and already
+ starts out horizontally.
+\stopitem
+\startitem
+ If the design complicates rule attachments, move to an extensible sooner
+ because that one can have a horizontal attachment point as part of the
+ design.
+\stopitem
+\stopitemize
+
+\startsubject[title=Removing slack]
+
+In the process of optimizing the spacing we ran into several cases where a bit of
+spacing was added that eventually made that the resulting formula had small quite
+visible whitespace at the edges. Take for instance the little bit of kerning
+between a nuclues and a superscript.
+
+\startlinecorrection
+\startMPcode
+ draw image (
+ draw fullsquare xyscaled(2, 4)
+ withcolor darkblue ;
+ draw fullsquare xyscaled(1/2, 1)
+ shifted (2-1/4,-1.5)
+ withcolor darkred ;
+ draw fullsquare xyscaled(1, 1)
+ shifted (3,2)
+ withcolor darkgray ;
+ ) scaled 5mm shifted (2cm, 0) ;
+\stopMPcode
+\stoplinecorrection
+
+Normally one can predict this situation but when components are glued together
+that are typeset independently the (in this case red) spacing remains. The engine
+is capable to remove that kind of slack at the left and right of the formula so
+that one gets a proper tight bounding box. There is a bit more logic on board now.
+
+The fact that all kind of spacing gets added is one of the reasons for the more
+granular inter atom spacing: that way we could remove for instance the spacing
+added to the left and right of fractions (which is buried in the constructed
+box).
+
+\startitemize[packed]
+\startitem
+ There is not much we can advice here because it doesn't relate to fonts.
+ However, given that Lucida text fonts have no kerning could make one wonder
+ to what extend math fonts needs all these compensations.
+\stopitem
+\startitem
+ Some of the inter atom|/|script kerning is probably there as safeguard for
+ italic shapes where staircase kerns are lacking. The question then is how the
+ related font parameters themselves relate to staircase kerns. We suppose that
+ this puts some stress on the font designer.
+\stopitem
+\stopitemize
+
+\stopsubject
+
+\page
+
+\startsubject[title=Initializing fonts]
+
+\startsubsubject[title=introduction]
+
+When a math font is initialized there are (as with any font) features applies.
+The only official one is the {ssty} feature that defines the substitution sets
+for script and scripscript size. In traditional \TEX\ one has to set up multiple
+fonts because one can only have 256 characters and because one might want to map
+alphabets on the regular \ASCII\ slots. In an \OPENTYPE\ font all these alphabets
+are on the same font so basically one can do with three instances per size: text,
+script and scriptscript. What actually is done depends on the philosophy of the
+macro package but we will not discuss that here. So let's assume three instances
+in the default case. In \LUAMETATEX\ we can scale on the fly and therefore we can
+stick to one instance: as long as we know what the slots of the (optionally
+provided) smaller sizes are. Supporting this had quite some consequences for the
+engine as scaling happens all over the place (also think of font parameters) and
+we're talking two independent dimensions here: horizontal and vertical sizing.
+
+In addition to this size related font feature \CONTEXT\ provide some additional
+ones (and always had). Some are set up as regular features and some are driven by
+the font goodie features which organizes a lot of features under one umbrella.
+Font goodies always have been part of \MKIV\ and \LMTX.
+
+{\em also mention the non tweak related ones}
+
+\stopsubsubject
+
+\startsubsubject[title=wipeitalics]
+
+This tweak wipes the italics from one or more characters, most noticeable upright
+characters. Because locating the individual characters took too much time, we
+added the option complete alphabets.
+
+\starttyping
+example
+\stoptyping
+
+\stopsubsubject
+
+\startsubsubject[title=wipeanchors]
+
+This tweak removes the top anchors from one or more characters, most noticeable
+upright characters. As with wiping italics, we often wipe complete alphabets.
+
+\starttyping
+example
+\stoptyping
+
+\stopsubsubject
+
+\startsubsubject[title=accentdimensions]
+
+Configure the position of overbar, underbar, overbrace, underbrace, overparent,
+underparent, overbracket and underbracket. More? Added 220307.
+
+\stopsubsubject
+
+\startsubsubject[title=addrules]
+
+I think we did not get overbars for some fonts (kpfonts and erewhon come to
+mind).
+
+\stopsubsubject
+
+\startsubsubject[title=addscripts]
+
+Maybe something done for Ton? (\typ{math-act})
+
+\stopsubsubject
+
+\startsubsubject[title=checkspacing]
+
+I don't know how it works. Seems there is not really any settings. But you once
+wrote
+
+\starttyping
+$\liminf$ \quad
+$\limsup$ \quad [\sixperemspace] \quad
+$x\sixperemspace x$
+
+\setbox0\hbox{$x\sixperemspace x$} \showbox0
+\stoptyping
+
+in an email (220118).
+
+\stopsubsubject
+
+\startsubsubject[title=dimensions]
+
+We use this to change anchor points of accents, to raise/lower them, and of
+course to change bounding boxes and italic correction for many letters/symbols.
+We use it in bonum to resize the whole lower case fraktur alphabet (and maybe
+more should be added)
+
+\stopsubsubject
+
+\startsubsubject[title=fixprimes]
+
+Maybe explained elsewhere? But it could belong here.
+
+\stopsubsubject
+
+\startsubsubject[title=fixradicals]
+
+I don't know what it does. Could be: In some fonts the radicals are just
+positioned wrongly, and this moves them up/down to have something uniform to work
+with. (\typ{math-act})
+
+\stopsubsubject
+
+\startsubsubject[title=kerns]
+
+A bit like staircase kerning. The \quote{topleft} and \quote{bottomright} come in
+handy, in particular the last one when it comes to the position of subscripts.
+
+\stopsubsubject
+
+\startsubsubject[title=margins]
+
+We fake the width of some characters. Useful, for example, not to get too
+large/too small accents when using \tex{widehat} (also to get a uniform size over
+some alphabets or glyphs that often go togeter).
+
+\stopsubsubject
+
+\startsubsubject[title=variants]
+
+Some fonts (lucida, xits, stixtwo) have calligraphic (chancery) and script
+(roundhand) alphabets. Of course not the same as default, and of course not the
+same ss0X.
+
+\stopsubsubject
+
+\startsubsubject[title=wipecues]
+
+Only added to cambria and dejavu. Added 220327. I think it has to do with
+characters like 2061, 2062 and 2063. From the mails I think it has why does 2061
+render a shape in some fonts so we need an 'wipe char' tweak (basically making it
+a zero dimensions symbol)
+
+\starttyping
+\mathspacingmode2
+\showmakeup[mathglue]
+$ \sin \Uchar"2061 (y) $ \quad
+$ x \Uchar"2062 y $ \quad
+$ x \Uchar"2063 y $ \par
+$ \sin \mathghost{\Uchar"2061} (y) $ \quad
+$ x \mathghost{\Uchar"2062} y $ \quad
+$ x \mathghost{\Uchar"2063} y $ \par
+\stoptyping
+
+\stopsubsubject
+
+\startsubsubject[title=bigslots]
+
+Fences are chosen automatically to match what they surround. However, in traditional
+engines a fenced sub formula won't break across lines. In \CONTEXT\ we have sveral st
+
+1, 3, 5, 7 that could fit here, if we find a font where the linking is not
+present.
+
+\stopsubsubject
+
+\startsubsubject[title=parameters]
+
+I don't know if all of them are parameters that typically moved from document to
+font level.
+
+\stopsubsubject
+
+\stopsubject
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-nostalgic-pgc.pdf b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-nostalgic-pgc.pdf
new file mode 100644
index 00000000000..77e20c6fb79
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-nostalgic-pgc.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-nostalgic.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-nostalgic.tex
new file mode 100644
index 00000000000..26b646625dc
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-nostalgic.tex
@@ -0,0 +1,268 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\startcomponent ontarget-nostalgic
+
+\environment ontarget-style
+
+\startchapter[title={Getting nostalgic}]
+
+When Mikael and I were playing with \POTRACE\ we eventually ended up by turning
+some old rune font defined in \METAFONT\ into a quite useable outline font. In
+the process we went from a \TYPETHREE\ to a proper \OPENTYPE\ (\CFF) instance.
+When doing this I remembered that in the times of active \PDFTEX\ development,
+Thanh, Taco and I played with what we called \PDF\ glyph containers. I had done
+experiments with using xforms (small images) as replacement for bitmap characters
+but that is not what we want with fonts, so after discussing it with Thanh
+\TYPETHREE\ support was extended with a user driven variant. Due to the way
+\METAFONT s are defined the results were mixed. Filled shapes could be made to
+work but outlines often looked bad and much had to do with the fact that these
+fonts were never defined with odd-even rules in mind. So, Taco made a bitmap to
+outline program that we could hook in and in the end we had a reasonable
+workflow. We're talking of the period 1997 to 1998, some 25 years ago!
+
+So, when in 2023 we came back to bitmap fonts in the perspective of \LUAMETATEX,
+some memories returned but I couldn't find the files or code at that time, which
+might relate to the fact that I always start from specifications. However, when
+in January 2024 I had to fix some issue with embedding an old \TYPEONE\ font and
+after succeeding in that I decided again to search for that old code. This time I
+just grep'd the \PDFTEX\ code base (as I had the \TEXLIVE\ git checkout) and I
+found back this feature. In the end I had been looking at the wrong \quote
+{strings} because it looked like the interface evolved a little.
+
+The basics are as follows. When we have a file (in \PDFTEX) the \TFM\ blob is
+what matters for the frontend. The backend that does the inclusion links that to
+a suitable font resource, most likely in \TYPEONE\ format. This is specified in a
+map file that also permits specifying an encoding vector. For some reason it is
+not possible to map to other font formats other than \TYPEONE\ and \TRUETYPE. No
+mapping means that a \PK\ file is used and then we end up in some complicated
+semi automatic bitmap generation.
+
+When I tested how these containers worked out nowadays, once \PDFTEX \footnote
+{Version 3.141592653-2.6-1.40.25 and older.} is happy to include a font it will
+bark about a missing font resource: it always wants a bitmap. Now, you can
+complain about this but I bet no one ever used this 25 year old feature so no one
+ever requested a check for a \type {pgc} file. Basically, when such a file is
+found instead of a \type{600pk} file, all should be fine, even if that is a zero
+length file. Given that the backend actually checks for it and not considers a
+container file useable, one can consider it an oversight, or maybe it just got
+lost in the \KPSE\ library that manages \PK\ fonts and its generation.
+
+Anyway, so how does it work? When the backend checks for a glyph container it
+expects this:
+
+\starttyping
+\pdffontscale factor
+\pdfglyph slot width height depth llx lly urx ury =
+ % pdf operators
+\endglyph
+\stoptyping
+
+One can add a \type {\pdffont} and \type{\endfont} wrapper because \PDFTEX\ only
+searches for the mandate scale and one or more glyphs. A simple test then becomes:
+
+\startitemize[packed]
+\startitem
+ Copy a \TFM\ file to a new name, say \type {cmr10mine.tfm}.
+\stopitem
+\startitem
+ Create a bogus \PK\ file, for instance a zero byte \type {cmr10mine.600pk}.
+\stopitem
+\startitem
+ Make sure it can be found, I had to set \type {set MISCFONTS=.}.
+\stopitem
+\startitem
+ Create a glyph container with suffix \type {pgc} with some valid \PDF\ code.
+\stopitem
+\stopitemize
+
+And then use a safe character for testing present in most fonts at the same
+position in the used encoding:
+
+\starttyping
+\starttext
+ \font\test=cmr10mine \test \char 65 % A
+\stoptext
+\stoptyping
+
+This should produce something, assuming an entry like:
+
+\starttyping
+\pdffontscale 0.01
+\pdfglyph 65 200 0 0 0 0 200 200 =
+ 10 M 1 j 1 J 5 w
+ % outlines
+ h S
+\endglyph
+\stoptyping
+
+Just for completeness, I could find a \PERL\ program on my disk that I wrote at
+that time and that has the banner:
+
+\starttyping
+mptopgc 1.01 - pdfTeX / HH 1998
+\stoptyping
+
+It produces help like:
+
+\starttyping
+ --silent use logfile instead of screen (no)
+ --autorun run MetaPost first (no)
+ --optimize convert gray into eofill (no)
+ --ignore ignore gray path (no)
+ --gray permit the gray operator (no)
+ --merge substitute gray using glyphs (no)
+--magnification set MetaPost mag factor (1)
+ --rounding alternative rounding offset (0)
+ --pgcpath pgc path
+ --tfmpath tfm file path
+ --tfmtopl ftmtopl binary name (tfmtopl)
+ --metapost metapost binary name (mpost)
+\stoptyping
+
+But it is a long time since I installed \PERL\ on my laptop so I didn't check it.
+I also found a manual that could be updated but I don't see much use for it now.
+There is even a \MKII\ \TEX\ file that one can run with \type {pdftex &plain
+\input supp-pgc.mkii \MPtoPGC} that produces container files but I didn't test
+that either.
+
+However, what I did test was if it still works. For that I used the following
+test file:
+
+\starttyping
+% engine=pdftex
+
+\startTEXpage[offset=10pt]
+
+\pdfmapline{texnansi-lmr10 < texnansi.enc}
+
+\font\test=texnansi-lmr10 \test
+
+\input tufte
+
+\stopTEXpage
+\stoptyping
+
+Here I use a normal \TFM\ file because after all we need the metrics. Then I made
+an empty \typ {texnansi-lmr10.600pk} so that we can fool the \PK\ generator. Using
+Latin Modern files is more convenient. The glyph container file was made by
+abusing some features of \LMTX:
+
+% \disabledirectives[fonts.streams.pack]
+
+\startitemize
+
+\startitem
+ With the module \type {s-fonts-outlines} I made a font sample that as
+ byproduct generates a file with outline definitions. Basically any attempt to
+ use an outline in \METAFUN\ will populate the cache. We load the font \type
+ {lmr10.afm} and it will get the outlines from \type {lmr10.pfb}. Of course
+ there are more that 256 characters in there but that doesn't matter.
+\stopitem
+
+\startitem
+ I also generated a \type {texnansi} vector file which can be done from a
+ normal \TEX\ run using the \LUA\ call \typ {fonts.encodings.load
+ ("texnansi.enc"))}. It locates and converts a regular \type{enc} into a \LUA\
+ representation. I picked up the file from the cache.
+\stopitem
+
+\startitem
+ From these files I generated a glyph container file \typ {texnansi-lmr10.pgc}
+ that can be used instead of the \PK\ file. The file \typ {mtx-pgc.lua} is
+ shown below.
+\stopitem
+
+\startitem
+ I made sure to set \type {MISCFONTS} to a sensible value because otherwise
+ the container file is not found (who knows what location strategy is used).
+\stopitem
+
+\stopitemize
+
+This is the \quote {quick and dirty} conversion file:
+
+\starttyping
+local round = math.round
+local concat = table.concat
+
+local result = { "\\pdffontscale 0.001\n" }
+local r = 1
+
+local f_pdfglyph = string.formatters["\\pdfglyph %i %i %i %i %i %i %i %i"]
+local s_endglyph = "\\endglyph\n"
+local f_comment = string.formatters["%% name %s index %i slot %i \n"]
+
+local shapes = table.load("lmr10-pfb.tma")
+local encoding = table.load("texnansi.tma")
+
+local glyphs = shapes.glyphs
+local hash = encoding.hash
+
+for index=0,#glyphs do
+ local glyph = glyphs[index]
+ local segments = glyph.segments or { }
+ local bounds = glyph.boundingbox or { 0, 0, 0, 0 }
+ local width = round(glyph.width or 0)
+ local name = glyph.name
+ local slotused = hash[name]
+ if slotused then
+ local llx, lly = bounds[1], bounds[2]
+ local urx, ury = bounds[3], bounds[4]
+ r = r + 1 ; result[r] = f_comment(name,index,slotused)
+ r = r + 1 ; result[r] = f_pdfglyph(slotused,width,0,0,llx,lly,urx,ury)
+ if #segments > 0 then
+ r = r + 1 ; result[r] = "10 M 1 j 1 J 0 w"
+ for i=1,#segments do
+ local s = segments[i]
+ if s[1] ~= "close" then
+ r = r + 1 ; result[r] = concat(s," ")
+ end
+ end
+ r = r + 1 ; result[r] = "h f*"
+ end
+ r = r + 1 ; result[r] = s_endglyph
+ end
+end
+
+io.savedata("texnansi-lmr10.pgc",concat(result,"\n"))
+\stoptyping
+
+Of course for a proper workflow we need to make this into a real helper script
+but here I just want to show the idea. The result is shown in \in {figure}
+[fig:pgcresult]. There is however one drawback: because \PDFTEX\ goes via the
+\PK\ route using the same font with a different scale will result in an extra
+copy while actually we have a scalable \TYPETHREE\ font. It is for that reason
+that I will not waste any more time on this. I could provide a patch to deal with
+it but changing a long time ago frozen \TEX\ program is tricky because bug(let)s
+have become features.
+
+\startplacefigure[title={This is what we get with glyph containers.},reference=fig:pgcresult]
+ \externalfigure
+ [ontarget-nostalgic-pgc.pdf]
+ [width=\textwidth,
+ background=color,
+ backgroundcolor=gray]
+\stopplacefigure
+
+So where does this bring us? Because \MKII\ is frozen and \PDFTEX\ only works
+with that version it makes no sense to add some kind of \TYPETHREE\ support. In
+\MKIV\ and \MKXL\ we have several mechanisms for creating these fonts anyway. I
+cannot comment on use outside \CONTEXT\ but because of the strong connection with
+\PK\ fonts being required in order for glyph containers to kick in at all, I
+suspect that it's a mostly unknown feature, but one that actually can be made to
+work. It could even work better (with respect to file lookup and font scaling)
+when it is decoupled from the \PK\ requirements and listen to na map file line
+that also signals if the font can be reused. But what worries me a bit more is
+that after 25 years I hardly recognize the (reasonable) \PERL\ code and little
+manual although it slowly came back. At that I time I could not have predicted
+where we are now with respect to \TYPETHREE\ support, which in \LMTX\ is very
+much kicking and alive. \footnote {At that time \TYPETHREE\ in the perspective of
+\TEX\ always had a bad ring, probably because the many files that were around
+with too low resolution bitmap fonts. The \PDF\ readers were not particularly
+good in rendering them either. But with outlines this format can be fun!}
+
+\stopchapter
+
+\stopcomponent
+
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-profiles.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-profiles.tex
new file mode 100644
index 00000000000..8607075710b
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-profiles.tex
@@ -0,0 +1,507 @@
+% language=us runpath=texruns:manuals/ontarget
+
+% timestamp: Scary Pockets with Leland Sklar: https://www.youtube.com/watch?v=1UOVLdPslmo
+% around 19 minutes in ... interesting! Hopefully I once see LS live!
+
+% we can yscale too
+
+\usebodyfont[modern,10pt]
+\usebodyfont[lucida,10pt]
+\usebodyfont[pagella,10pt]
+\usebodyfont[bonum,10pt]
+\usebodyfont[antykwa,10pt]
+
+\startcomponent ontarget-profiles
+
+\environment ontarget-style
+
+\startchapter[title={Profiles}]
+
+\startsection[title=Introduction]
+
+Among the typesetting problems that relate to math are inline formulas that have
+a bit too much height or depth but not so much as to justify some additional
+interline space. For that reason in \CONTEXT\ \MKII\ we have some snapping
+features that can be enabled that limit the dimensions. In \MKIV\ a more
+extensive profile feature was written (we talked about it at meetings in 2015)
+that look at the bottom and top of lines in order to determine if lines can be
+moved closer, but in practice snapping and profiling are never really used. In
+the end it was more an academic exercise which is not uncommon when it comes to
+\TEX\ user demands and practice.
+
+As part of exploring math micro typography these features surfaced again during
+some discussion about weird mechanisms and we actually wondered if we could revive
+this now that we also control other aspects of math typesetting in more detail.
+One condition is that the overhead is not that high. Users accept some overhead
+for protrusion and expansion that relate to horizontal optimization so a little
+extra overhead for vertical optimization should not be a problem.
+
+Of course, as with protrusion and especially expansion, the question is if
+readers will notice it. Best would be to set up some experiments but, although
+one can argue that research is important, in practice it always boils down to a
+visual impression, feel good and, like it or not, exploration, trial and error.
+And so a simplified variant of profiling was implemented and applied to a math
+intensive math book used in academia. Instead of proper experiments some unaware
+bystanders were asked if they noticed a difference and to our surprise that was
+the case! And these were not even math students but kids who were more familiar
+with children books and phones. That convinced us that we were on the right
+track, that we need to explain a little about what we actually do, and that we
+should tell users what to look at when this gets applied.
+
+With an introduction like this, mentioning \quote {research}, \quote {academia},
+\quote {students} and \quote {typography} we're sure that future generations will
+be convinced that what is discussed next has a strong fundament so here we go!
+
+\stopsection
+
+\startsection[title=A first example]
+
+We start with a simple example. Because in practice profiling always kicks in
+when possible one really need to handcraft an example that can be used for
+demonstration: \in {figure} [fig:profile].
+
+\definelineprofile[MyLineProfileA][step=1pt,factor=0.125]
+\definelineprofile[MyLineProfileB][step=1pt,factor=0.250]
+\definelineprofile[MyLineProfileC][step=1pt,factor=1.000]
+
+\startbuffer
+ \hsize 7cm
+ no no no no no no no no no no no no no no no no no \im{x^{2^{A^P}}+x_{2_g}}. no no no no no no no no no no no no no no no no no no no no no no no \im{\frac{1+A^{2^x}}{2+B_2}} no no no no no no no no no no no no no no no no no.\blank
+ no no no yes yes no no no no no no no no no no no \im{x^{2^{A^P}}+x_{2_g}}. no no no no no no no no yes yes no no no no no no no no no no no no \im{\frac{1+A^{2^x}}{2+B_2}} no no no no no no no no no no no no no no no no no.\par
+\stopbuffer
+
+\startbuffer[set]
+\showmakeup[line]
+\enabletrackers[profiling.lines.show]
+\stopbuffer
+
+\startbuffer[reset]
+\disabletrackers[profiling.lines.show]
+\stopbuffer
+
+\startplacefigure[reference=fig:profile]
+\startcombination[2*2]
+ {\getbuffer[set]\vbox{\hsize7cm\resetlineprofile \getbuffer}\getbuffer[reset]}{\type{no profile}}
+ {\getbuffer[set]\vbox{\hsize7cm\setlineprofile [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
+ {\getbuffer[set]\vbox{\hsize7cm\setlineprofile [MyLineProfileB]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.250}}
+ {\getbuffer[set]\vbox{\hsize7cm\setlineprofile [MyLineProfileC]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=1.000}}
+\stopcombination
+\stopplacefigure
+
+In order to see what happens it is important to understand how \TEX\ sees lines.
+Actually, the concept of lines in \TEX\ is rather limited: lines are just
+horizontal boxes where the baselines are separated by \type {\baselineskip} and
+when the distance is larger than that dimensions a \type {\lineskip} gets added.
+
+\appendtoks\showmakeup[reset]\to\everybeforeoutput
+
+\startlines \showmakeup[line]
+these are a few
+lines of text
+where lines have depths
+or no real
+height at all
+\stoplines
+
+Between all these lines some skip needs to be added: the \type {\baselineskip}
+minus the height and depth. If we add struts the lines get the optimal height and
+depth so then no skips are inserted:
+
+\startlines \showmakeup[line] \showstruts
+\strut these are a few
+\strut lines of text
+\strut where lines have depths
+\strut or no real
+\strut height at all
+\stoplines
+
+When we increase the depth a little, for instance 1.2 times the normal strut depth,
+we see that some additional space, the \type {\lineskip} gets added:
+
+\startlines \showmakeup[line] \showstruts
+\strut these {\vrule depth 1.2\strutdp width .25em \relax} are a few
+\strut lines of {\vrule depth 1.2\strutdp width .25em \relax} text
+\strut where lines have {\vrule depth 1.2\strutdp width .25em \relax} depths
+\strut or {\vrule depth 1.2\strutdp width .25em \relax} no real
+\strut height at {\vrule depth 1.2\strutdp width .25em \relax} all
+\stoplines
+
+However, there is no real reason to do that here because the
+larger rules don't clash with text or other content. So this is what we get when
+we pass the \type {profile} option to \type {\setupalign}:
+
+\def\MyStrut{\vrule depth 1.2\strutdp width .25em \relax}
+
+\enabletrackers[profiling.lines.show]
+\startpacked \setupalign[profile]
+\strut these {\MyStrut} are a few \crlf
+\strut lines of {\MyStrut} text \crlf
+\strut where lines have {\MyStrut} depths \crlf
+\strut or {\MyStrut} no real \crlf
+\strut height at {\MyStrut} all
+\stoppacked
+\disabletrackers[profiling.lines.show]
+
+Profiling works per paragraph, so when we add a \type {\par} in the middle we get
+this:
+
+\enabletrackers[profiling.lines.show]
+\startpacked \setupalign[profile]
+\strut these {\MyStrut} are a few \crlf
+\strut lines of {\MyStrut} text \crlf
+\strut where lines have {\MyStrut} depths \par
+\strut or {\MyStrut} no real \crlf
+\strut height at {\MyStrut} all
+\stoppacked
+\disabletrackers[profiling.lines.show]
+
+But, we can actually setup the profiler to look back. Setting up the main
+(document) profiler happens with:
+
+\starttyping
+\setuplineprofile
+ [factor=0.125, % default
+ paragraph=yes, % default: no
+ step=0.5\emwidth] % default
+\stoptyping
+
+but as with most \CONTEXT\ mechanisms you can define your own profiler. The step
+tells what granularity to use when comparing positions in a line. The factor sets
+the threshold for the interline skip. We saw these two differ in the first
+example we gave.
+
+\stopsection
+
+\startsection[title=Profiled math]
+
+We will give several examples of math profiling.
+In the examples we will switch font to Latin Modern,
+since the effect is more visible for that font.
+Most of our examples will be \quotation{real} (slightly modified) ones,
+but we start with a rather artificial example. Below we have
+two occurrences of a fraction. Note that the profiling only kicks
+in for the second one. The reason is that on the line above the first
+one we only have letters (x) with no depth, while in the second one,
+we have added one letter (g) that has depth.
+
+\startbuffer \hsize 8cm
+xxx xxxx xxxx xx xxx xx xx xxx xxxx xxx xx xxx xxx xx xx xxx x xxxxx xxxxx
+xxx xxxx xxxx xx xxx xx xx xxx xxxx xxx xx xxx xxx xx xx xxx x xxxxx xxxxx
+\im{\frac{1}{2}} xxx xxx xx xx xxx xxxx xxxxxxx xxxx xxxx xxxxx xxx xxxx xxx
+xxx xxx xxx xxx xxx xxxx xxxxxx xxxxxxx xxxgxxx xxx xxx xxx xx x xxxxxxx xxx
+\im{\frac{1}{2}} xxx xxxx xxxx xx xxx xx xx xxx xxxx xxx xx xxx xxx xx xx
+xxx x xxxxx xxxxx.\par
+\stopbuffer
+
+\starttextdisplay
+\switchtobodyfont[modern,9pt]
+\startcombination[nx=2,ny=1,distance=1cm]
+ {\getbuffer[set]\vtop{\hsize8cm\resetlineprofile \getbuffer}\getbuffer[reset]}{\type{no profile} }
+ {\getbuffer[set]\vtop{\hsize8cm\setlineprofile [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
+\stopcombination
+\stoptextdisplay
+
+We next show a simple paragraph where the mechanism gets applied in three out of five line breaks.
+
+\startbuffer \hsize 8cm
+The results of Section 6.3 show that the same phenomenon is encountered when
+treating the norms of inverses: \im{\fenced[doublebar][size=0]{B_n^{-1}}_p}
+converges to \im{N_p} very fast if \im{N_p > N_p^0}, while the convergence
+may be slow if \im{N_p = N_p^0}. As the following proposition reveals, at
+least for \im{p = 2} the strict inequality \im{N_2 > N_2^0} is the generic
+case.\par
+\stopbuffer
+
+\starttextdisplay
+\startcombination[nx=2,ny=1,distance=1cm]
+ {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\resetlineprofile \getbuffer}\getbuffer[reset]}{\type{no profile} }
+ {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
+\stopcombination
+\stoptextdisplay
+
+We have shown the lines and used the helper to show where the profiling
+is applied. We show the same example but without these helpers. After
+all, this is how we usually see it.
+
+\starttextdisplay
+\startcombination[nx=2,ny=1,distance=1cm]
+ {\switchtobodyfont[modern,9pt]\vtop{\hsize8cm\resetlineprofile \getbuffer}\getbuffer[reset]}{\type{no profile} }
+ {\switchtobodyfont[modern,9pt]\vtop{\hsize8cm\setlineprofile [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
+\stopcombination
+\stoptextdisplay
+
+If the paragraph is slightly reformulated, the profiling might change.
+Below we show an example where the subscript (p) on the fourth line gets
+too close to the superscript (0) on the last line.
+
+\startbuffer \hsize 8cm
+The results of Section 6.3 show that the same phenomenon is encountered when
+treating the norms of inverses: \im{\fenced[doublebar][size=0]{B_n^{-1}}_p}
+converges to \im{N_p} very fast if \im{N_p > N_p^0}, while the convergence
+may be slow if \im{N_p = N_p^0}.
+At least for \im{p = 2} the strict inequality \im{N_2 > N_2^0} is the generic
+case.\par
+\stopbuffer
+
+\starttextdisplay
+\startcombination[nx=2,ny=1,distance=1cm]
+ {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\resetlineprofile \getbuffer}\getbuffer[reset]}{\type{no profile} }
+ {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
+\stopcombination
+\stoptextdisplay
+
+We can configure the amount of space that shall be added with the \type{factor} key.
+
+% MS: Fixing a shift issue in the one below took one timestamp loop:
+
+\starttextdisplay
+\startcombination[nx=2,ny=1,distance=1cm]
+ {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125} }
+ {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile [MyLineProfileC]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=1}}
+\stopcombination
+\stoptextdisplay
+
+\startbuffer \hsize 8cm
+This shows that the sequence \im{(f_n)} is a Cauchy sequence in \im{L^1(\reals)}
+and therefore it converges in norm to some \im{\sum_{k=1}^n \hat{f} \in L^1(\reals)}, by
+Thereom~2.8.1. On the other hand, by Theorem~2.8.2, there exists an increasing
+sequence of positive integers \im{q_n} such that \im{f_{q_n} \to \tilde{f}}
+almost everywhere.\par
+\stopbuffer
+
+\starttextdisplay
+\startcombination[nx=2,ny=2,distance=1cm]
+ {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\resetlineprofile \getbuffer}\getbuffer[reset]}{\type{no profile} }
+ {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
+\stopcombination
+\stoptextdisplay
+
+\stopsection
+
+\startsection[title=Line spacing]
+
+When we enable the line profiler on a 300 page math course with plenty inline
+formulas, the number of \quote {corrections} varies a lot with the fonts. Some
+simple tests show that Latin Modern, Bonum and EBGaramond get quite some applied,
+while Lucida, Dejavu, Antykwa, Erewhon and Libertinus only see a few corrections.
+Pagella, Termes and StixTwo end up in the middle.
+
+The trigger is not always text or math. The course material has quite some
+structure, like numbered descriptions. In \CONTEXT\ we use plenty of struts to
+make sure that spacing is consistent and the keyword that starts a description
+therefore gets them. Normally that is not an issue but when the height of the
+next line exceeds the strut height we get a clash and line skip will be added.
+One can argue that the strut spoils the typesetting but in general it does more
+good than harm, at least in \CONTEXT. It looks like the profiler is quite capable
+of getting rid of the cases where it interferes (or more precisely: where it
+doesn't run into the next line).
+
+The reason why we get a line skip added is simple: when the depth of the first
+line equals strut depth and the height of the second one equals strut height
+we're okay. When one of them is less we're also okay because \TEX\ will adapt the
+baseline skip so that it compensated the difference. However, when the first line
+has strut depth (due to the present strut) and the second line more than strut
+height (resulting for instance from a formula) the lines are considered
+overflowing in each other and therefore interline skip gets added.
+
+When we end up in this situation the profiler can bring down the line skip when
+it concludes that the strut is not running into the next line. However when the
+formula sits directly below the strut we cannot really determine what is right so
+then we just keep the skip. This situation occurs seldom. In many cases struts
+are optional so one can always disable them (locally).
+
+As the mentioned test document uses Lucida as body font, in the three cases where
+we actually get a clash, one definitely relates to the strut: the overflow in the
+second line occurs close to the right margin and the strut in the first line sits
+at the left margin so we can get rid of the line skip, which leave us with only
+two cases. However, there is another observation, one that involves the baseline
+distance or line height.
+
+In \CONTEXT\ the ratio between the strut height and depth is 72:28 which works
+quite well for most fonts. If we look at Lucida shapes we see that the depth is
+normally small so we can actually decide to change that ratio. It is however not
+clear how that will influence decisions. Assuming more height will help with for
+instance formulas that have superscripts, but an inline integral with subscript
+might suffer. For other fonts, like EBGaramond, that have some extremely deep
+shapes changing rations won't help anyway. We win here and loose there.
+
+\startbuffer[text-001]
+ abcdefghijklmnopqrstuvwxyz
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ
+ 1234567890
+ ()[]/\{\}\|
+ .,!?@\#\$\%^&*_-+=
+\stopbuffer
+
+\startbuffer[math-001]
+ $\int\sum\sqrt{}$
+\stopbuffer
+
+\startbuffer[math-002]
+ x_2^2
+\stopbuffer
+
+\newbox\MyHtDpBoxA
+\newbox\MyHtDpBoxB
+\newbox\MyHtDpBoxC
+
+\def\CheckThemA#1%
+ {\begingroup
+ \switchtobodyfont[#1,10pt]%
+ \starttabulate[||r|]
+ \FL
+ \BC \rlap{#1} \NC \NC \NR
+ \FL
+ \NC strut ht \EQ \the\strutht \NC \NR
+ \NC strut dp \EQ \the\strutdp \NC \NR
+ % \NC height \EQ \meaningless\strutheightfactor \NC \NR
+ % \NC depth \EQ \meaningless\strutdepthfactor \NC \NR
+ \NC ex \EQ \the\exheight \NC \NR
+ \LL
+ \stoptabulate
+ \endgroup}
+
+\def\CheckThemB#1%
+ {\begingroup
+ \switchtobodyfont[#1,10pt]%
+ \setbox\MyHtDpBoxA\ruledhpack\bgroup\inlinebuffer[text-001]\egroup
+ \setbox\MyHtDpBoxB\ruledhpack\bgroup\inlinebuffer[math-001]\egroup
+ \setbox\MyHtDpBoxC\ruledhpack\bgroup\inlinebuffer[math-002]\egroup
+ \def\ShowThem##1##2%
+ {\cldcontext{"\letterpercent 0.2f",\number##1##2/\number\htdp##2}
+ \NC
+ \the##1##2%
+ \NC}
+ \starttabulate[|r|r|i2r|r|i2r|r|]
+ \FL
+ \NS[1][c] \bf text-001
+ \NS[1][c] \bf math-001
+ \NS[1][c] \bf math-002
+% \rlap{\quad\quad#1}
+ \NR
+ \FL
+ \NC
+ \ShowThem\ht\MyHtDpBoxA
+ \ShowThem\ht\MyHtDpBoxB
+ \ShowThem\ht\MyHtDpBoxC
+ \NR
+ \NC
+ \ShowThem\dp\MyHtDpBoxA
+ \ShowThem\dp\MyHtDpBoxB
+ \ShowThem\dp\MyHtDpBoxC
+ \NR
+ \LL
+ \stoptabulate
+ \endgroup}
+
+We will look into a few fonts to get a better impression how all this relates. We
+will use 10pt sizes. When we compare Lucida, Latin Modern, Bonum and Pagella we
+notice that we start out with design sizes that are quite different.
+
+\CheckThemA{lucida}
+\CheckThemA{modern}
+\CheckThemA{bonum}
+\CheckThemA{pagella}
+
+This is why we always use ratios (the 0.72 and 0.28) as well as abstract
+dimensions like \type {ex} and \type {em} so that we adapt to what the font
+provides. Because the default (total) line height is set to \type {2.8ex} we get
+larger values in for instance Lucida.
+
+In the next tables we use three samples, with \type {text-001} being:
+
+\typebuffer[text-001]
+
+The two math samples are:
+
+\typebuffer[math-001]
+
+and
+
+\typebuffer[math-002]
+
+For text the ratios are not that far off the defaults, but for math they start
+to differ and the distance becomes larger. For Lucida we get:
+
+\CheckThemB{lucida}
+
+Modern gives:
+
+\CheckThemB{modern}
+
+And bonum moves in the other direction:
+
+\CheckThemB{bonum}
+
+Pagella also differs:
+
+\CheckThemB{pagella}
+
+Changing the ratios for the sake of math makes not that much sense because
+profiling depends a lot on what math ends up inline. When we looked around a bit
+for realistic examples we got the impression that seeing some clash (read:
+getting uneven line spacing) might be a reason why small formulas eventually end
+up as display. Without mentioning names, we noticed that a reprint of a book
+actually got reformatted and when we looked for the slashing formulas in the
+original they had become display instead. With proper profiling there is no need
+for that. On top of that one can argue that some inline rendering can be done
+better anyway, like using skewed fraction instead of ruled ones. Can we predict
+that math with many superscripts goes well with a font with relatively high
+shapes? As soon as some parenthesis are used we get depth anyway and how likely
+is it that math without these is used inline? It also depends on the amount of
+math: two lines with superscripted math will drive \TEX\ to use line skip so we
+need to profile anyway. For that reason we will not adapt the ratios, just like
+we keep the default line spacing. There are of course fonts with extreme heights
+(like the Computer Modern Dunhill variant) but no one will use those artistic
+variants in a math document. If you want to go fancy and distinctive, Antykwa is
+a good choice and that one actually scores pretty good with the defaults!
+
+\CheckThemA{antykwa}
+
+\CheckThemB{antykwa}
+
+\stopsection
+
+\startsection[title=Conclusion]
+
+So, should we enable profiling on mixed text|-|math documents or not? One
+possible reason for not doing it is that it adds overhead, but in practice it's
+not that much compared to processing the rest. It is no problem to find
+complaints on the internet about \LUATEX\ performing worse than its ancestors so
+if you're in that category: don't use profiling because it sets you back a few
+percent runtime. However, when you're a demanding \CONTEXT\ user who mixes in a
+lot of math, you might give it a try. It will intercept a couple of cases where
+struts (assuming structure is used) trigger a line skip, and it might also catch
+a couple of cases where \TEX\ found lines getting too close. Tweaking the \type
+{factor} and \type {step} can actually be fun. Because it does influence page
+breaks it is not something to be applied last minute. And, talking performance,
+this kind of vertical optimization comes cheaper than horizontal optimization
+using expansion (hz) and protrusion.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
+
+% \framed[width=7cm,offset=overlay,align={lohi,normal}]{\getbuffer}
+% \framed[width=7cm,offset=overlay,align={lohi,normal,profile}]{\getbuffer}
+
+% maybe add an interline callback ...
+
+% Test different fonts
+% lots: modern, bonum, ebgaramond,
+% some: pagella, termes, stixtwo
+% few: lucida, dejavu, antykwa, kurier, erewhon, libertinus
+
+% Strut can force lineheight and depth.
+
+% antykwa size of vertical bar is maybe too big. Change step?
+
+% antykwa \Biggl(1+\frac{1}{n}\Biggr)^n
+
+% cambria, superscripts sit a bit high (we did not change it)
+
+% the role of font parameters (superscripts... not enough steps in i.e. square roots)
+
+% dp / ht relation and struts
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-radicals.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-radicals.tex
new file mode 100644
index 00000000000..ef2103d349f
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-radicals.tex
@@ -0,0 +1,160 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\startcomponent ontarget-radicals
+
+\environment ontarget-style
+
+\startchapter[title={Somewhat radical}]
+
+Here we will discuss an aspect of radicals, namely how variants get applied. Take
+the following situation:
+
+\startbuffer[one]
+\dontleavehmode \glyphscale 4000
+\ruledhbox{\setupmathradical[sqrt][mindepth=0pt,strut=no,leftmargin=0pt]$\sqrt{x+1}$ $\sqrt{x-1}$}\blank
+\ruledhbox{\setupmathradical[sqrt][mindepth=0pt,strut=no,leftmargin=0pt]$\sqrt{1+x}$ $\sqrt{1-x}$}
+\stopbuffer
+
+\startbuffer[two]
+\dontleavehmode \glyphscale 4000
+\ruledhbox{\setupmathradical[sqrt][mindepth=0pt,strut=no,leftmargin=0pt]$\sqrt{\frac{x+1}{x-1}}$}
+\ruledhbox{\setupmathradical[sqrt][mindepth=0pt,strut=no,leftmargin=0pt]$\sqrt{\frac{1+x}{1-x}}$}
+\stopbuffer
+
+\startbuffer[three]
+\dontleavehmode \glyphscale 4000
+\ruledhbox{$\sqrt{\frac{x+1}{x-1}}$}
+\ruledhbox{$\sqrt{\frac{1+x}{1-x}}$}
+\stopbuffer
+
+\startlinecorrection
+\switchtobodyfont[modern-nt]\getbuffer[one]
+\stoplinecorrection
+
+Watch the slight difference in radical heights. Now look at this:
+
+\startlinecorrection
+\switchtobodyfont[modern-nt]\getbuffer[two]
+\stoplinecorrection
+
+Here we need to make sure that we don't run into the slope, because, when we have
+a close look at the shapes we see that the radical symbol has a tight bounding
+box:
+
+\startlinecorrection
+\showglyphs\switchtobodyfont[modern-nt]\getbuffer[one]
+\stoplinecorrection
+
+In pagella we get:
+
+\startlinecorrection
+\showglyphs\switchtobodyfont[pagella-nt]\getbuffer[two]
+\stoplinecorrection
+
+and in antykwa:
+
+\startlinecorrection
+\showglyphs\switchtobodyfont[antykwa]\getbuffer[two]
+\stoplinecorrection
+
+But now look at this formula:
+
+\startlinecorrection
+\switchtobodyfont[antykwa]
+{\showglyphs \showstruts \getbuffer[three]}
+{\getbuffer[three]}
+\stoplinecorrection
+
+Here we see several mechanisms in action and for a good reason. First of all we
+want similar subformulas (under the symbol) to have compatible radicals. For this
+we use special struts so that we always have at least some height. We also
+compensate for slight differences in depth by setting a minimum depth. Finally we
+add a bit of margin. That last feature moves the content free from the symbols
+which means that we can have less distance between the top of the content and the
+rule. In many fonts that distance is set to a value that prevents clashes and the
+more slope we have, the more opportunity there is to clash.
+
+When the best fit decision is made for a radical, the effective height of the
+content (height plus depth of the box) is incremented by a gap variable. The
+standard specifies the \typ {RadicalVerticalGap} as \quotation {Space between the
+(ink) top of the expression and the bar over it. Suggested: 1.25 default rule
+thickness.} and \typ {RadicalDisplayStyleVerticalGap} as \quotation {Space
+between the (ink) top of the expression and the bar over it. Suggested: default
+rule thickness plus .25 times x-height.}. These values are actually rather font
+dependent because the slope needs to be taken into account; there is also a
+visual aspect to it.
+
+We can't tweak the radical width because the rule has to be attached. If we could
+we'd have to do it for every variant. So, instead we set up radical like this:
+
+\starttyping
+\setupmathradical
+ [strut=height, % only height
+ leftmargin=.05mq, % fraction of math quad
+ mindepth=.05mx] % fraction of math x height
+\stoptyping
+
+When deciding what size to use, a list of variants is followed till there is a
+match and when we run out of variants an extensible is constructed. Here is the
+list of possible sizes in the current font:
+
+\startbuffer[four]
+\startformula
+ \glyphscale 2000
+ \dorecurse {\nofmathvariants "221A} {
+ \ruledhbox{$\char \getmathvariant #1 "221A \relax$}
+ \quad
+ }
+\stopformula
+\stopbuffer
+
+\startbuffer[five]
+\startformula
+ \glyphscale 2000
+ \dorecurse {\nofmathvariants "221A} {
+ \setbox\scratchbox\ruledhbox{$\char \getmathvariant #1 "221A$}
+ \raise\dp\scratchbox\box\scratchbox
+ \quad
+ }
+\stopformula
+\stopbuffer
+
+\getbuffer[four]
+
+However, when we don't center around the math axis we get a more distinctive view
+on the steps:
+
+\getbuffer[five]
+
+It will be clear that the steps can't be too large but there are fonts out there
+that behave rather extreme, like Cambria:
+
+{\switchtobodyfont[cambria-nt] \getbuffer[five]}
+
+The only way out here is to either inject scaled variants into the list of
+possibilities or to simply ignore all except the first one and go straight to the
+extensible, so that's what we do, in combination with tweaked parameters and a
+margin:
+
+{\switchtobodyfont[cambria] \getbuffer[five]}
+
+As with many font parameters (also in text) one sometimes wonder if font designer
+test with real examples. There are of course exceptions, for instance the \typ
+{ebgaramond} font, but that one goes over the top in other areas. Here one can
+also wonder if the upper half of the range makes sense over an extensible. For
+consistency one wants steps to be not too small, so that a sequence of radicals
+looks simular, but steps larger than for instance the height are probably bad.
+
+\pushoverloadmode
+{\switchtobodyfont[ebgaramond] \let\quad\thinspace \getbuffer[five]}
+\popoverloadmode
+
+So, as with other examples that we give of tweaking math, it is clear that there
+is no way around also tweaking radicals, and we're not even talking of the way we
+fine tune the positioning of degrees in radicals because that is also a neglected
+area in \OPENTYPE\ math fonts.
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-standardize.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-standardize.tex
new file mode 100644
index 00000000000..255cba3eba7
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-standardize.tex
@@ -0,0 +1,987 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\setupexternalfigures[directory=screendumps]
+
+\usebodyfont[antykwa]
+\usebodyfont[modern-nt]
+\usebodyfont[modern]
+\usebodyfont[bonum-nt]
+\usebodyfont[bonum]
+\usebodyfont[lucida-nt]
+\usebodyfont[lucida]
+\usebodyfont[erewhon-nt]
+\usebodyfont[erewhon]
+\usebodyfont[libertinus-nt]
+\usebodyfont[libertinus]
+\usebodyfont[stixtwo]
+\usebodyfont[cambria]
+
+\hyphenation{prime-shift-up-cramped}
+
+\startcomponent ontarget-standardize
+
+\environment ontarget-style
+
+\startchapter[title={Standardizing math fonts}]
+
+\startsection[title={Introduction}]
+
+\CONTEXT\ has always had a good support for the typesetting of mathematics.
+\CONTEXT\ \MKII\ uses the \PDFTEX\ engine and hence traditional (\TYPEONE) fonts.
+Several math fonts are available, specifically designed to work seamlessly with
+\TEX. \CONTEXT\ \MKIV, the successor version, utilizes the \LUATEX\ engine,
+providing support not only for traditional fonts but also for \OPENTYPE\
+\UNICODE\ math fonts. Unlike the \XETEX\ engine, which interpreted these new
+fonts in a manner similar to traditional \TEX\ fonts, \LUATEX\ adheres more
+closely to the (unfortunately somewhat vague) \OPENTYPE\ specification. \footnote
+{See \typ{https://learn.microsoft.com/en-us/typography/opentype/spec/math}} When
+new fonts appeared, some were more like the traditional fonts, others more like
+\OPENTYPE\ \UNICODE\ math fonts. This leads to difficulties in achieving
+consistent results across different fonts and might be one reason that the
+\UNICODE\ engines are not yet used as much as they probably should.
+
+In autumn 2021 we started to discuss how to improve the typesetting of \OPENTYPE\
+\UNICODE\ mathematics, and it was natural to go on and do this for the
+\LUAMETATEX\ engine, and hence for \CONTEXT\ \LMTX. Since then, we have been
+engaging in daily discussions covering finer details such as glyphs, kerning,
+accent placement, inter|-|atom spacing (what we refer to as math
+microtypography), as well as broader aspects like formula alignment and formula
+line breaking (math macrotypography). This article will primarily focus on the
+finer details. Specifically, we will explore the various choices we have made
+throughout the process. The \OPENTYPE\ \UNICODE\ math specification is
+incomplete; some aspects are missing, while others remain ambiguous. This issue
+is exacerbated by the varying behaviors of fonts.
+
+We make runtime changes to fonts, and add a few additional font parameters that
+we missed. As a result, we deviate from the standard set by Microsoft (or rather,
+we choose to interpret it in our own way) and exercise the freedom to make
+runtime changes to font parameters. Regarding this aspect, we firmly believe that
+our results often align more closely with the original intentions of the font
+designers. Indeed, the existence of \quotation{oddities} in these fonts may be
+attributed to the lack of an engine, during their creation, that supported all
+the various features, making testing difficult, if not essentially impossible.
+Within \CONTEXT\ \LMTX, we have the necessary support, and we can activate
+various helpers that allow us to closely examine formulas. Without them our work
+would not have been possible.
+
+Ultimately, we hope and believe that we have made straightforward yet effective
+choices, rendering the existing \OPENTYPE\ \UNICODE\ math fonts usable. We hope
+that this article might be inspiring and useful for others who aim to achieve
+well|-|designed, modern math typesetting.
+
+\stopsection
+
+\startsection[title={Traditional vs.\ \OPENTYPE\ math fonts}]
+
+There is a fundamental difference between traditional \TEX\ math fonts and
+\OPENTYPE\ \UNICODE\ fonts. In the traditional approach, a math setup consists of
+multiple independent fonts. There is no direct relationship between a math italic
+$x$ and an $\hat{\hphantom{x}}$ on top of it. The engine handles the positioning
+almost independently of the shapes involved. There can be a shift to the right of
+$\hat{x}$ triggered by kerning with a so|-|called skew character but that is it.
+
+A somewhat loose coupling between fonts is present when we go from a base
+character to a larger variant that itself can point to a larger one and
+eventually end up at an extensible recipe. But the base character and that
+sequence are normally from different fonts. The assumption is that they are
+designed as a combination. In an \OPENTYPE\ font, variants and extensibles more
+directly relate to a base character.
+
+Then there is the italic correction which adds kerns between a character and what
+follows depending on the situation. It is not, in fact, a true italic correction,
+but more a hack where an untrue width is compensated for. A traditional \TEX\
+engine defaults to adding these corrections and selectively removes or
+compensates for them. In traditional \TEX\ this fake width helps placing the
+subscript properly while the italic correction is added to the advance width when
+attaching subscripts and|/|or moving to the next atom.
+
+In an \OPENTYPE\ font we see these phenomena translated into features. Instead of
+many math fonts we have one font. This means that one can have relations between
+glyphs, although in practice little of that happens. One example is that a
+specific character can have script and scriptscript sizes with a somewhat
+different design. Another is that there can be alternate shapes for the same
+character, and yet another is substitution of (for instance) dotted characters by
+dotless ones. However, from the perspective of features a math font is rather
+simple and undemanding.
+
+Another property is that in an \OPENTYPE\ math font the real widths are used in
+combination with optional italic correction when a sequence of characters is
+considered text, with the exception of large operators where italic correction is
+used for positioning limits on top and below. Instead of abusing italic
+corrections this way, a system of staircase kerns in each corner of a shape is
+possible.
+
+Then there are top (but not bottom) anchor positions that, like marks in text
+fonts, can be used to position accents on top of base characters or boxes. And
+while we talk of accents: they can come with so|-|called flat substitutions for
+situations where we want less height.
+
+All this is driven by a bunch of font parameters that (supposedly) relate to the
+design of the font. Some of them concern rules that are being used in
+constructing, for instance, fractions and radicals but maybe also for making new
+glyphs like extensibles, which is essentially a traditional \TEX\ thing.
+
+So, when we now look back at the traditional approach we can say that there are
+differences in the way a font is set up: widths and italic corrections, staircase
+kerns, rules as elements for constructing glyphs, anchoring of accents,
+flattening of accents, replacement of dotted characters, selection of smaller
+sizes, and font parameters. These differences have been reflected in the way
+engines (seem to) deal with \OPENTYPE\ math: one can start with a traditional
+engine and map \OPENTYPE\ onto that; one can implement an \OPENTYPE\ engine and,
+if needed, map traditional fonts onto the way that works; and of course there can
+be some mix of these.
+
+In practice, when we look at existing fonts, there is only one reference and that
+is Cambria. When mapped onto a traditional engine, much can be made to work, but
+not all. Then there are fonts that originate in the \TEX\ community and these do
+not always work well with an \OPENTYPE\ engine. Other fonts are a mix and work
+more or less. The more one looks into details, the clearer it becomes that no
+font is perfect and that it is hard to make an engine work well with them. In
+\LUAMETATEX\ we can explicitly control many of the choices the math engine makes,
+and there are more such choices than with traditional \TEX\ machinery. And
+although we can adapt fonts at runtime to suit the possibilities, it is not
+pretty.
+
+This is why we gradually decided on a somewhat different approach: we use the
+advantage of having a single font, normalize fonts to what we can reliably
+support, and if needed, add to fonts and control the math engine, especially the
+various subsystems, with directives that tell it what we want to be done. Let us
+discuss a few things that we do when we load a math font.
+
+\stopsection
+
+\startsection[title={Getting rid of italic corrections}]
+
+\OPENTYPE\ math has italic corrections for using characters in text and large
+operators (for limits), staircase kerns for combining scripts, and top anchor for
+placement of accents. In \LUAMETATEX\ we have access to more features.
+
+Let's remind ourselves. In a bit more detail, \OPENTYPE\ has:
+
+\startitemize[packed]
+\startitem
+ \typ An \typ {italic correction} is injected between characters in running
+ text, but: a sequence of atoms is {\em not} text, they are individually
+ spaced.
+\stopitem
+\startitem
+ An \typ {italic correction} value in large operators that reflects where
+ limits are attached in display mode; in effect, using the italic
+ correction as an anchor.
+\stopitem
+\startitem
+ \typ {Top anchors} are used to position accents over characters, but
+ not so much over atoms that are composed from not only characters.
+\stopitem
+\startitem
+ \typ {Flat accents} as substitution feature for situations where the height
+ would become excessive.
+\stopitem
+\startitem
+ \typ {Script and scriptscript} as substitution feature for a selection of
+ characters that are sensitive for scaling down.
+\stopitem
+\stopitemize
+
+This somewhat limited view on math character positioning has been extended in
+\LUAMETATEX, and we remap the above onto what we consider a bit more reliable,
+especially because we can tweak these better. We have:
+
+\startitemize[packed]
+\startitem
+ \typ {Corner kerns} that make it possible to adjust the horizontal location
+ of sub- and superscripts and prescripts.
+\stopitem
+\startitem
+ Although \typ {flat accents} are an existing feature, we extended them by
+ providing additional scaling when they are not specified.
+\stopitem
+\startitem
+ In addition to script sizes we also have \typ {mirror} as a feature so that
+ we can provide right to left math typesetting. (This also relates to
+ dropping in characters from other fonts, like Arabic.)
+\stopitem
+\startitem
+ In addition to the \typ {top anchors} we also have \typ {bottom anchors}
+ in order to properly place bottom accents. These are often
+ missing, so we need to construct them from available snippets.
+\stopitem
+\startitem
+ An additional \typ {extensible italic correction} makes it possible to
+ better anchor scripts to sloped large operators. This is combined with
+ keeping track of \typ {corner kerns} that can be specified per character.
+\stopitem
+\startitem
+ Characters can have \typ {margins} which makes it possible to more precisely
+ position accents that would normally overflow the base character and clash
+ with scripts. These go in all four directions.
+\stopitem
+\startitem
+ In order to be able to place the degree in a radical more precisely (read:
+ not run into the shape when there is more than just a single degree atom) we
+ have \typ {radical offsets}.
+\stopitem
+\stopitemize
+
+There are plenty more tuning options but some are too obscure to mention here.
+All high level constructors, like fences, radicals, accents, operators,
+fractions, etc.\ can be tuned via optional keyword and key|/|values at the macro
+end.
+
+We eliminate the italic correction in math fonts, instead adding it to the width,
+and using a negative bottom right kern. If possible we also set a top and bottom
+accent anchor. This happens when we load the font. We also translate the italic
+correction on large operators into anchors. As a result, the engine can now
+completely ignore italic corrections in favor of proper widths, kerns and
+anchors. Let us look at a few examples.
+
+The italic $f$ is used a lot in mathematics and it is also one of the most
+problematic characters. In \TEXGYRE\ Bonum Math the italic f has a narrow
+bounding box; the character sticks out on both the left and right. To the right,
+this is compensated by a large amount of italic correction. This means that when
+one adds sub- and superscripts, it works well. We add italic correction to the
+width, and introducing a negative corner kern at the bottom right corner, and
+thus the placement of sub- and superscripts is not altered. Look carefully at the
+bounding boxes below.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,distance=1es]
+ \startcontent
+ \switchtobodyfont[bonum-nt]
+ \showglyphs
+ \dm{\setmscale{3}f_0^1}
+ \stopcontent
+ \startcaption
+ \hbox {original}
+ \stopcaption
+ \startcontent
+ \showglyphs
+ \dm{\setmscale{3}f_0^1}
+ \stopcontent
+ \startcaption
+ \hbox {tweaked}
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+Compare with Lucida Bright Math, which comes with staircase kerns instead of
+italic correction. We convert these kerns into corner kerns.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,distance=5ts]
+ \startcontent
+ \switchtobodyfont[lucida-nt]
+ \showglyphs
+ \dm{\setmscale{3}f_0^1}
+ \stopcontent
+ \startcaption
+ \hbox {original}
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[lucida]
+ \showglyphs
+ \dm{\setmscale{3}f_0^1}
+ \stopcontent
+ \startcaption
+ \hbox {tweaked}
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+For characters that stick out to the left, we also increase the width and shift
+the glyph to ensure that it does not stick out on the left side. This prevents
+glyphs from clashing into each other.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,distance=5ts]
+ \startcontent
+ \switchtobodyfont[bonum-nt]
+ \showglyphs
+ \dm{\setmscale{3}(f)}
+ \stopcontent
+ \startcaption
+ \hbox {original}
+ \stopcaption
+ \startcontent
+ \showglyphs
+ \dm{\setmscale{3}(f)}
+ \stopcontent
+ \startcaption
+ \hbox {tweaked}
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+As mentioned, for the integral, one of the most common big operators, the limits
+are also placed with help of the italic correction. When the limits go below and
+on top, proper bottom and top anchor points are introduced, calculated from the
+italic correction. (The difference in size of the integral signs is a side effect
+of the font parameter \typ {DisplayOperatorMinHeight} being tweaked, as we'll
+discuss more later. \OPENTYPE\ fonts can come with more than two sizes.)
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=3,distance=5ts]
+ \startcontent
+ \switchtobodyfont[bonum-nt]
+ \showglyphs
+ \dm{\setmscale{1.5}\int_a^b f(x) \dd x}
+ \stopcontent
+ \startcaption
+ original
+ \stopcaption
+ \startcontent
+ \showglyphs
+ \dm{\setmscale{1.5}\int_a^b f(x) \dd x}
+ \stopcontent
+ \startcaption
+ \hbox {tweaked, nolimits}
+ \stopcaption
+ \startcontent
+ \setupmathematics
+ [integral=limits]
+ \showglyphs
+ \dm{\setmscale{1.5}\int_a^b f(x) \dd x}
+ \stopcontent
+ \startcaption
+ \hbox {tweaked, limits}
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+Compare these integrals with the summation, that usually does not have any italic
+correction bound to it. This means that the new anchor points end up in the
+middle of the summation symbol.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,distance=5ts]
+ \startcontent
+ \switchtobodyfont[bonum-nt]
+ \showglyphs
+ \dm{\setmscale{1.5}\sum_{k=1}^{n}a_k}
+ \stopcontent
+ \startcaption
+ original
+ \stopcaption
+ \startcontent
+ \showglyphs
+ \dm{\setmscale{1.5}\sum_{k=1}^{n}a_k}
+ \stopcontent
+ \startcaption
+ tweaked
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+We also introduce some corner kerns in cases where there were neither italic
+corrections nor staircase kerns. This is mainly done for delimiters, like
+parentheses. We can have a different amount of kerning for the various sizes.
+Often the original glyph does not benefit from any kerning, while the variants
+and extensibles do.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,distance=5ts]
+ \startcontent
+ \switchtobodyfont[bonum-nt]
+ \showglyphs
+ \dm{\setmscale{1.5}\left( \frac {1}{1 + x^2} \right)^2}
+ \stopcontent
+ \startcaption
+ original
+ \stopcaption
+ \startcontent
+ \showglyphs
+ \dm{\setmscale{1.5}\left( \frac {1}{1 + x^2} \right)^2}
+ \stopcontent
+ \startcaption
+ tweaked
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+Note also the different sizes of the parentheses in the example above. Both
+examples are set with \typ {\left(} and \typ {\right)}, but the font parameters
+are chosen differently in the tweaked version. Font designers should have used
+the opportunity to have more granularity in sizes. Latin Modern Math has four,
+many others have steps in between, but there is a lack of consistency.
+
+\stopsection
+
+\startsection[title={Converting staircase kerns}]
+
+We simplify the staircase kerns, which are often somewhat sloppy and seldom
+complete (see figure below), into more reliable corner kerns. It's good enough
+and looks better on the whole. We also avoid bugs that way.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,ny=1,distance=5TS]
+ \startcontent
+ \clip[ny=3,y=2]
+ {\externalfigure[CambriaItalicV-bottomrightkern][height=3ES]}
+ \stopcontent
+ \startcaption
+ italic V
+ \stopcaption
+ \startcontent
+ \clip[ny=3,y=2]
+ {\externalfigure[CambriauprightV-bottomrightkern][height=3ES]}
+ \stopcontent
+ \startcaption
+ upright V
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+
+\stopsection
+
+\startsection[title={Tweaking accents}]
+
+We ignore the zero dimensions of accents, simply assuming that one cannot know if
+the shape is centered or sticks out in a curious way, and therefore use proper
+widths with top and bottom anchors derived from the bounding box. We compensate
+for negative llx values being abused for positioning. We check for overflows in
+the engine. In case of multiple accents, we place the first one anchored over the
+character, and center the others on top of it.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=1,distance=5TS]
+ \startcontent
+ \switchtobodyfont[bonum]
+ \showglyphs
+ \dm{\setmscale{3} \hat{\hat{\hat{f}}}}
+ \stopcontent
+ \startcaption
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+We mentioned in an earlier \TUGBOAT\ article that sometimes anchor points are
+just wrong. We have a tweak that resets them (to the middle) that we use for
+several fonts and alphabets.
+
+Some accents, like the hat, can benefit from being scaled. The fonts typically
+provide the base size and a few variants.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,ny=1,distance=5TS]
+ \startcontent
+ \switchtobodyfont[bonum-nt]
+ \showglyphs
+ \dm{\setmscale{3}\widehat[stretch=no]{f+g}}
+ \stopcontent
+ \startcaption
+ original
+ \stopcaption
+ \startcontent
+ \showglyphs
+ \dm{\setmscale{3}\widehat{f+g}}
+ \stopcontent
+ \startcaption
+ tweaked
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+The only fonts we have seen that support flattened accents are Stix Two Math
+and Cambria Math.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,ny=1,distance=1es]
+ \startcontent
+ \switchtobodyfont[stixtwo]
+ \showglyphs
+ \dm{\setmscale{3}\hat{a}\hat{A}\hat{C}}
+ \stopcontent
+ \startcaption
+ stix two
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[cambria]
+ \showglyphs
+ \dm{\setmscale{3}\hat{a}\hat{A}\hat{C}}
+ \stopcontent
+ \startcaption
+ cambria
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+If you look carefully, you notice that the hats over the capital letters are not
+as tall as the one over the lowercase letter. There is a font parameter \typ
+{FlattenedAccentBaseHeight} that is supposed to specify when this effect is
+supposed to kick in. Even though other fonts do not use this feature, the
+parameter is set, sometimes to strange values (if they were to have the
+property). For example, in Garamond Math, the value is 420.
+
+We introduced a tweak that can fake the flattened accents, and therefore we need
+to alter the value of the font parameter to more reasonable values. We
+communicated to Daniel Flipo, who maintains several math fonts, that the
+parameter was not correctly set in Erewhon math. In fact, it was set such that
+the flattened accents were used for some capital letters (C in the example below)
+but not for others (A below). He quickly fixed that. The green rules in the
+picture have the height of \typ {FlattenedAccentBaseHeight}; it did not need to
+be decreased by much.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,distance=5TS]
+ \startcontent
+ \externalfigure[erewhonmath][page=1]
+ \stopcontent
+ \startcaption
+ \hbox{Erewhon, not fixed}
+ \stopcaption
+ \startcontent
+ \externalfigure[erewhonmath][page=2]
+ \stopcontent
+ \startcaption
+ \hbox{Erewhon, fixed}
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+\stopsection
+
+\startsection[title={Getting rid of rules}]
+
+We get rid of rules as pseudo-glyphs in extensibles and bars. This also gives
+nicer visual integration because flat rules do not always fit in with the rest of
+the font. We also added support for this in the few (Polish) Type~1 math fonts
+that we still want to support, like Antykwa Toruńska.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+\startcombination[nx=3,ny=1,distance=5TS]
+\startcontent
+\switchtobodyfont[modern-nt]%
+\setupmathfractions
+ [strut=no]%
+\dm{
+ \setmscale{3}
+ \sqrt{\frac{1+x}{1-x}}
+}
+\stopcontent
+\startcaption
+With rule
+\stopcaption
+
+\startcontent
+\switchtobodyfont[modern]%
+\setupmathfractions
+ [strut=no]%
+\dm{
+ \setmscale{3}
+ \sqrt{\frac{1+x}{1-x}}
+}
+\stopcontent
+\startcaption
+With glyph
+\stopcaption
+\startcontent
+\switchtobodyfont[antykwa]%
+\setupmathfractions
+ [strut=no]%
+\dm{
+ \setmscale{3}
+ \sqrt{\frac{1+x}{1-x}}
+}
+\stopcontent
+\startcaption
+Antykwa
+\stopcaption
+\stopcombination
+\stopplacefloat
+
+Here is an enlarged example of an Antykwa rule. Latin Modern has rounded corners,
+here we see a rather distinctive ending.
+
+\startlinecorrection
+\scale[height=2cm]{\switchtobodyfont[antykwa]\im{\overbar{x^2 + 2x + 2}}}
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Tweaking primes}]
+
+We make it no secret that we consider primes in math fonts a mess. For some
+reason no one could convince the \UNICODE\ people that a \quote {prime} is not a
+\quote {minute} (that is, \acro{U+2032 PRIME} is also supposed to be used as the
+symbol for minutes); in case you'd like to argue that \quotation {they often look
+the same}, that is also true for the Latin and Greek capital \quote {A}. This
+lost opportunity means that, as with traditional \TEX\ fonts, we need to fight a
+bit with placement. The base character can or cannot be already anchored at some
+superscript|-|like position, so that makes it basically unusable. An alternative
+assumption might be that one should just use the script size variant as a
+superscript, but as we will see below, that assumes that they sit on the baseline
+so that we can move it up to the right spot. Add to that the fact that
+traditional \TEX\ has no concept of a prime, and we need some kind of juggling
+with successive scripts. This is what macro packages end up doing.
+
+But this is not what we want. In \CONTEXT\ \MKIV\ we already have special
+mechanisms for dealing with primes, which include mapping successive primes onto
+the multiple characters in \UNICODE, where we actually have individual triple and
+quadruple primes and three reverse (real) primes as well. However, primes are now
+a native feature, like super- and subscripts, as well as prescripts and indices.
+(All examples here are uniformly scaled.)
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=3,ny=6]
+ \startcontent
+ \externalfigure[Latinmodernprime][scale=200]
+ \stopcontent
+ \startcaption
+ lm
+ \stopcaption
+ \startcontent
+ \externalfigure[Latinmodernprimest][scale=200]
+ \stopcontent
+ \startcaption
+ st
+ \stopcaption
+ \startcontent
+ \externalfigure[Latinmodernprimests][scale=200]
+ \stopcontent
+ \startcaption
+ sts
+ \stopcaption
+ \startcontent
+ \externalfigure[Lucidaprime][scale=200]
+ \stopcontent
+ \startcaption
+ lucida
+ \stopcaption
+ \startcontent
+ \stopcontent
+ \startcaption
+ \stopcaption
+ \startcontent
+ \externalfigure[Lucidaprimessty][scale=200]
+ \stopcontent
+ \startcaption
+ ssty
+ \stopcaption
+ \startcontent
+ \externalfigure[Erewhonprime][scale=200]
+ \stopcontent
+ \startcaption
+ erewhon
+ \stopcaption
+ \startcontent
+ \externalfigure[Erewhonprimest][scale=200]
+ \stopcontent
+ \startcaption
+ st
+ \stopcaption
+ \startcontent
+ \externalfigure[Erewhonprimesst][scale=200]
+ \stopcontent
+ \startcaption
+ sst
+ \stopcaption
+ \startcontent
+ \externalfigure[Libertinusprime][scale=200]
+ \stopcontent
+ \startcaption
+ libertinus
+ \stopcaption
+ \startcontent
+ \externalfigure[Libertinusprimessty1][scale=200]
+ \stopcontent
+ \startcaption
+ ssty1
+ \stopcaption
+ \startcontent
+ \stopcontent
+ \startcaption
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+Because primes are now a native feature, we also have new font parameters \typ
+{PrimeShiftUp} and \typ {PrimeShiftUpCramped}, similar to \typ
+{SuperscriptShiftUp} and \typ {SuperscriptShiftUpCramped}, which add a horizontal
+axis where the primes are placed. There is also a \typ {fixprimes} tweak that we
+can use to scale and fix the glyph itself. Below, we see how very different the
+primes from different fonts look (all examples are uniformly scaled), and then
+examples comparing the original and tweaked primes.
+
+\startbuffer
+\dm{\setmscale{2}f'(x) + e^{f'(x)}}
+\stopbuffer
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=2,ny=4,distance=2ts]
+ \startcontent
+ \switchtobodyfont[modern-nt]
+ \getbuffer
+ \stopcontent
+ \startcaption
+ lm original
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[modern]
+ \getbuffer
+ \stopcontent
+ \startcaption
+ lm tweaked
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[lucida-nt]
+ \getbuffer
+ \stopcontent
+ \startcaption
+ lucida original
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[lucida]
+ \getbuffer
+ \stopcontent
+ \startcaption
+ lucida tweaked
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[erewhon-nt]
+ \getbuffer
+ \stopcontent
+ \startcaption
+ erewhon original
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[erewhon]
+ \getbuffer
+ \stopcontent
+ \startcaption
+ erewhon tweaked
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[libertinus-nt]
+ \getbuffer
+ \stopcontent
+ \startcaption
+ libertinus original
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[libertinus]
+ \getbuffer
+ \stopcontent
+ \startcaption
+ libertinus tweaked
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+\stopsection
+
+\startsection[title={Font parameters}]
+
+We add some font parameters, ignore some existing ones, and fix at runtime those
+that look to be suboptimal. We have no better method than looking at examples, so
+parameters might be fine|-|tuned further in the future.
+
+We have already mentioned that we have a few new parameters, \typ {PrimeShiftUp}
+and \typ {PrimeShiftUpCramped}, to position primes on their own axis, independent
+of the superscripts. They are also chosen to always be placed outside
+superscripts, so the inputs \typ {$f'^2$} and \typ {$f^2'$} both result in
+$f^2'$. Authors should use parentheses in order to avoid confusion.
+
+\startplacefloat
+ [intermezzo]
+ [location=nonumber]
+ \startcombination[nx=1,ny=3]
+ \startcontent
+ \externalfigure[latex-pdfpowers-crop][scale=1.2*2400]
+ \stopcontent
+ \startcaption
+ \stopcaption
+ \startcontent
+ \externalfigure[latex-luapowers-crop][scale=1.2*2400]
+ \stopcontent
+ \startcaption
+ \stopcaption
+ \startcontent
+ \externalfigure[230430-3-crop][scale=1.2*2000]
+ \stopcontent
+ \startcaption
+ \stopcaption
+ \stopcombination
+\stopplacefloat
+
+Let us briefly mention the other parameters. These are the adapted parameters for
+\TeX\ Gyre Bonum:
+
+\starttyping
+AccentTopShiftUp = -15
+FlattenedAccentTopShiftUp = -15
+AccentBaseDepth = 50
+DelimiterPercent = 90
+DelimiterShortfall = 400
+DisplayOperatorMinHeight = 1900
+SubscriptShiftDown = 201
+SuperscriptShiftUp = 364
+SubscriptShiftDownWithSuperscript = "1.4*SubscriptShiftDown"
+PrimeShiftUp = "1.25*SuperscriptShiftUp"
+PrimeShiftUpCramped = "1.25*SuperscriptShiftUp"
+\stoptyping
+
+Some of these are not in \OPENTYPE. We can set up much more, but it depends on
+the font what is needed, and also on user demands.
+
+We have noticed that many font designers seem to have had problems setting some
+of the values; for example, \typ {DisplayOperatorMinHeight} seems to be off in
+many fonts.
+
+\stopsection
+
+\startsection[title={Profiling}]
+
+Let us end with profiling, which is only indirectly related to the tweaking of
+the fonts. Indeed, font parameters control the vertical positioning of sub- and
+superscripts. If not carefully set, they might force a non-negative \tex {
+lineskip} where not necessary. In the previous section we showed how these
+parameters were tweaked for Bonum.
+
+Sometimes formulas are too high (or have a too large depth) for the line, and so
+a \tex {lineskip} is added so that the lines do not clash. If the lowest part of
+the top line (typically caused by the depth) and the tallest part of the bottom
+line (caused by the height) are not close to each other on the line, one might
+argue that this \tex {lineskip} does not have to be added, or at least with
+reduced amount. This is possible to achieve by adding \typ
+{\setupalign[profile]}. Let us look at one example.
+
+\startbuffer[annals]
+So the question is: how good an approximation to \im {\sigma} is \im {\sigma * W
+\phi}? But the attentive reader will realize that we have already answered this
+question in the course of proving the sharp GÃ¥rding inequality. Indeed, suppose
+\im{\phi \in \mathcal{S}} is even and \im {\fenced[doublebar]{\phi}_2 = 1}, and
+set \im {\phi^a(x) = a^{n/4} \phi (a^{1/2}x)}. Then we have shown (cf.\ Remark
+(2.89)) that \im {\sigma - \sigma * W\phi^a \in S_{\rho, \delta}^{m-(\rho-
+\delta)}} whenever \im {\sigma \in S_{\rho, \delta}^m} is supported in a set
+where \im {\langle \xi \rangle^{\rho + \delta} \approx a}.
+\stopbuffer
+
+\starttextdisplay
+\bgroup
+\switchtobodyfont[modern]%23cm
+\startcombination[nx=1,ny=2]
+\startcontent
+\vtop{\hsize 14cm\relax%
+\showmakeup[line]
+\getbuffer[annals]}
+\stopcontent
+\startcaption
+No profiling
+\stopcaption
+\startcontent
+\vtop{\hsize 14cm\relax%
+\setupalign[profile]
+\showmakeup[line]
+\enabletrackers[profiling.lines.show]
+\getbuffer[annals]}
+\stopcontent
+\startcaption
+Profiling
+\stopcaption
+\stopcombination
+\egroup
+\stoptextdisplay
+
+In the above paragraphs we enabled a helper that shows us where the profiling
+feature kicks in. We also show the lines (\typ {\showmakeup[line]}). Below we
+show the example without those helpers. You can judge for yourself which one you
+prefer.
+
+\starttextdisplay
+\bgroup
+\switchtobodyfont[modern]
+\startcombination[nx=1,ny=2]
+\startcontent
+\vtop{\hsize 14cm\relax%
+\getbuffer[annals]}
+\stopcontent
+\startcaption
+No profiling
+\stopcaption
+\startcontent
+\vtop{\hsize 14cm\relax%
+\setupalign[profile]
+\disabletrackers[profiling.lines.show]
+\getbuffer[annals]}
+\stopcontent
+\startcaption
+Profiling
+\stopcaption
+\stopcombination
+\egroup
+\stoptextdisplay
+
+It is worth emphasizing that, contrary to what one might believe at first, the
+profiling does not substantially affect the compilation time. On a 300-page math
+book we tried, which usually compiles in about 10 seconds, profiling did not add
+more than 0.5 seconds. The same observation holds for the other math tweaks we
+have mentioned: the overhead is negligible.
+
+\stopsection
+
+\startsection[title={Conclusions}]
+
+All these tweaks can be overloaded per glyph if needed; for some fonts, we indeed
+do this, in so|-|called goodie files. The good news is that by doing all this we
+present the engine with a font that is consistent, which also means that we can
+more easily control the typeset result in specific circumstances.
+
+The reader may wonder how we ended up with this somewhat confusing state of
+affairs in the font world. Here are some possible reasons. There is only one
+reference font, Cambria, and that uses its reference word processor renderer,
+Word. Then came \XETEX\ that as far as we know maps \OPENTYPE\ math onto a
+traditional \TEX\ engine, so when fonts started coming from the \TEX\ crowd,
+traditional dimensions and parameters sort of fit in. When \LUATEX\ showed up, it
+started from the other end: \OPENTYPE. That works well with the reference font
+but less so with that ones coming from \TEX. Eventually more fonts showed up, and
+it's not clear how these got tested because some lean towards the traditional and
+others towards the reference fonts. And, all in all, these fonts mostly seem to
+be rather untested in real (more complex) math.
+
+The more we looked into the specific properties of \OPENTYPE\ math fonts and
+rendering, the more we got the feeling that it was some hybrid of what \TEX\ does
+(with fonts) and ultimately desired behavior. That works well with Cambria and a
+more or less frozen approach in a word processor, but doesn't suit well with
+\TEX. Bits and pieces are missing, which could have been added from the
+perspective of generalization and imperfections in \TEX\ as well. Lessons learned
+from decades of dealing with math in macros and math fonts were not reflected in
+the \OPENTYPE\ fonts and approach, which is of course understandable as
+\OPENTYPE\ math never especially aimed at \TEX. But that also means that at some
+point one has to draw conclusions and make decisions, which is what we do in
+\CONTEXT, \LUAMETATEX\ and the runtime|-|adapted fonts. And it gives pretty good
+and reliable results.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-style.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-style.tex
index eac3ffe3183..515bc1123ec 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-style.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget-style.tex
@@ -5,8 +5,6 @@
\usemodule[abbreviations-smallcaps]
\usemodule[scite]
-\enableexperiments[fonts.compact]
-
\logo [LUAMETATEX] {LuaMeta\TeXsuffix}
\setupbodyfont[plex,10pt] % not that ok for titling
@@ -57,7 +55,8 @@
[tolerant,stretch]
\setuptyping
- [color=maincolor]
+ [color=maincolor,
+ align=hangright]
\setuptype
[color=maincolor]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget.tex b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget.tex
index 888a73f4198..3129a53e7d9 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/ontarget/ontarget.tex
@@ -27,7 +27,32 @@
\component ontarget-gettingridof
\component ontarget-registers
\component ontarget-fairphone
+ \component ontarget-green
+ \component ontarget-jmn
+ \component ontarget-profiles
+ \component ontarget-envelopes
+ \component ontarget-mathfonts
% \component ontarget-mathsizes
+ \component ontarget-constants
+ \component ontarget-active
+ \component ontarget-accuracy
+ \component ontarget-mathcharacters
+ \component ontarget-standardize
+ \component ontarget-radicals
+ \component ontarget-bars
+ % \component ontarget-rules.tex
+ % \component ontarget-bitmaps.tex
+ % \component ontarget-rivers.tex
+ % \component ontarget-inclusion.tex
+ % \component ontarget-signing.tex
+ % \component ontarget-authentic.tex
+ % \component ontarget-dimensions
+ % \component ontarget-pagestreams
+ % \component ontarget-mathml
+ \component ontarget-nostalgic
\stopbodymatter
\stopdocument
+
+% ontarget-wrapup.tex
+% ontarget-done.tex
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/pdfmerge/pdfmerge-testfiles.zip b/Master/texmf-dist/doc/context/sources/general/manuals/pdfmerge/pdfmerge-testfiles.zip
new file mode 100644
index 00000000000..e0148f8f625
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/pdfmerge/pdfmerge-testfiles.zip
Binary files differ
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/pdfmerge/pdfmerge.tex b/Master/texmf-dist/doc/context/sources/general/manuals/pdfmerge/pdfmerge.tex
new file mode 100644
index 00000000000..26acefe82c9
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/pdfmerge/pdfmerge.tex
@@ -0,0 +1,604 @@
+% language=us runpath=texruns:manuals/pdfmerge
+
+% The font merge feature is also availble in \MKIV\ where it is an experiment and
+% some cleanup is also there. In \LMTX\ it's more mature. Thanks to the competent
+% Team Ramkumar (including Syabil and Fish) for providing input, testing this
+% extensively, and feed back.
+
+% \nopdfcompression
+
+\usemodule[abbreviations-logos]
+
+\setupbodyfont
+ [bonum,10pt]
+
+\setuplayout
+ [topspace=.05ph,
+ bottomspace=.05ph,
+ backspace=.05ph,
+ header=.05 ph,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setupwhitespace
+ [big]
+
+\setuphead
+ [chapter]
+ [style=\bfc,
+ headerstate=high,
+ interaction=all]
+
+\setuphead
+ [section]
+ [style=\bfb]
+
+\setuphead
+ [subsection]
+ [style=\bfa]
+
+\setuphead
+ [subsubsection]
+ [style=\bf,
+ after=]
+
+\setuplist
+ [interaction=all]
+
+\setuptyping
+ [color=darkyellow]
+
+\enabletrackers[graphics.fonts]
+\enabletrackers[graphics.fixes]
+
+\startdocument
+ [title=PDFmerge,
+ author=Hans Hagen]
+
+\startMPpage
+ fill Page withcolor "darkyellow" ;
+
+ picture p[] ;
+
+ p1 := image ( draw textext.ulft("PDF")
+ ysized 4cm
+ shifted lrcorner Page
+ withcolor "white"
+ ; );
+ p2 := image ( draw textext.ulft("\strut merging, embedding, fixing")
+ xsized bbwidth p[1]
+ shifted lrcorner Page
+ withcolor "lightgray"
+ ; );
+ p3 := image ( draw textext.ulft("\strut and messing a bit around")
+ xsized bbwidth p[1]
+ shifted lrcorner Page
+ withcolor "lightgray"
+ ; );
+ p4 := image ( draw textext.ulft("\strut in context lmtx")
+ xsized bbwidth p[1]
+ shifted lrcorner Page
+ withcolor "lightgray"
+ ; );
+ draw p[4] shifted (-1cm,1cm) ;
+ draw p[3] shifted (-1cm,1cm+bbheight(p4)+0cm) ;
+ draw p[2] shifted (-1cm,1cm+bbheight(p3)+bbheight(p4)+0cm) ;
+ p[1] := p[1] shifted (-1cm,1cm+bbheight(p2)+bbheight(p3)+bbheight(p4)+15mm);
+ save dy ; dy := 0 ;
+ for i=0 upto 7 :
+ p[1] := p[1] yscaled (1-i/80) ;
+ draw p[1]
+ shifted (0,dy)
+ withtransparency (1,.8-i/10) ;
+ dy := dy + .6*bbheight(p[1]) ;
+ endfor ;
+\stopMPpage
+
+\startluacode
+ backends.registered.pdf.codeinjections.registercompactor {
+ name = "preset:mine",
+ identify = {
+ content = true,
+ resources = true,
+ page = true,
+ },
+-- embed = {
+-- type0 = true,
+-- truetype = true,
+-- type1 = true,
+-- },
+ merge = {
+ type0 = true, -- check if a..z A..Z 0..9
+ truetype = true,
+ type1 = true,
+ LMTX = true,
+ },
+ strip = {
+-- group = true,
+-- extgstate = true,
+ marked = true,
+ },
+-- reduce = {
+-- color = true,
+-- rgb = true,
+-- cmyk = true,
+-- },
+-- convert = {
+-- rgb = true,
+-- cmyk = true,
+-- },
+-- add = {
+-- cidset, -- when missing or even fix
+-- },
+ recolor = {
+ viagray = { 1, 0, 0 },
+-- viagray = { 0, 1, 0 },
+-- viagray = { 0, 1, 0, .5 },
+-- viagray = { .75 },
+ }
+ }
+\stopluacode
+
+\starttext
+
+The three graphic formats that make most sense for inclusion in \PDF\ are \PNG,
+\JPG, and \PDF. The easiest if these is \JPG\ because basically the binary blob
+get transferred to the result file. A \PNG\ graphic might need more work because
+what actually is supported is basic \PNG\ inclusion. It means that often the
+image data has to be unpacked and split into \PDF\ counterparts that get
+embedded. The \PDF\ format is quite convenient because basically we only need to
+copy the used objects to the result, so when those object are for instance \PNG\
+encoded images, we gain runtime, but when we're talking pages of documents it
+might take some more. Nevertheless, in practice it is still quite efficient.
+
+Here we focus on \PDF\ inclusion where we have sereral scenarios to deal with:
+
+\startitemize[packed]
+ \startitem
+ A straightforward inclusion of a single page \PDF\ file.
+ \stopitem
+ \startitem
+ Inclusion of a specific page from a \PDF\ file.
+ \stopitem
+ \startitem
+ Inclusion of several pages from a \PDF\ file.
+ \stopitem
+ \startitem
+ Inclusion of one or more pages from several \PDF\ files.
+ \stopitem
+\stopitemize
+
+To this we can add:
+
+\startitemize
+ \startitem
+ Inclusion of one or more pages from \PDF\ files that are generated
+ independently (subruns) for instance in the process of writing a manual
+ about something \CONTEXT. Think of externaly processed buffers.
+ \stopitem
+\stopitemize
+
+When we include more than one page from a file, we only need to embed shared
+objects once. Of course it demands some object management but that has to be done
+anyway. We could share objects across files but that demands more memory and
+runtime and the saving are likely to be small, with one exception: fonts. It
+would be nice if we can embed missing fonts and also merge fonts that are the
+same. This can make the result much smaller, especially when we're talking of
+including examples of typesetting in a manual that uses the same fonts.
+
+Another aspect of inclusion is the quality of the to be embedded page. Here you
+can think of errors in the page stream, color spaces that don't match, missing
+properties, invalid metadata, etc. Often there's not much we can do about it, but
+sometimes we can. However, it has to happen under user control and the outcome
+has to be checked, although often a visual check is good enough.
+
+The \type {compact} parameter of \type {\externalfigure} controls the embedding
+of \PDF\ content. When set to \quote {yes} it will merge fonts but only when the
+file is produced by \CONTEXT\ \LMTX. The reason for not checking all fonts by
+default comes from the fact that references from the page stream to glyphs in the
+font depend on the application that made the \PDF. In some cases the mapping is
+using the original glyph index, but one can never be sure. Using the \type
+{tounicode} map to go from page stream index to glyph index is also not reliable
+because multiple glyphs can have the same \UNICODE\ slot and when font features
+are applied (say small caps) you actually don't know that.
+
+The mentioned \type {yes} option is a preset that has been defined like:
+
+\starttyping
+\startluacode
+graphics.registerpdfcompactor ( "yes", {
+ merge = {
+ lmtx = true,
+ },
+} )
+\stopluacode
+\stoptyping
+
+Another preset is \type {merge}:
+
+\starttyping
+\startluacode
+graphics.registerpdfcompactor ( "merge", {
+ merge = {
+ type0 = true,
+ truetype = true,
+ type1 = true,
+ lmtx = true,
+ },
+} )
+\stopluacode
+\stoptyping
+
+Currently we don't support \TYPETHREE\ optimization. It is doable but probably
+not worth the effort.
+
+We can also force embedding of fonts that are not included in the document that
+we get the page from. This is unlikely unless you have old documents.
+
+\starttyping
+embed = {
+ type0 = true,
+ truetype = true,
+ type1 = true,
+}
+\stoptyping
+
+References to glyphs in the page stream use an eight bit string encoding or an
+hexadecimal byte pairs. Depending on the font type we have upto 256 references
+(using one character or two hex bytes) or at most 65536 references (using two
+characters or 4 hex bytes). We normalize everything to hex encoding. That way we
+get rid of the ugly escapes and exceptions in page stream glyph string.
+
+There are two trackers:
+
+\starttyping
+\enabletrackers[graphics.fonts]
+\enabletrackers[graphics.fixes]
+\stoptyping
+
+The first one reports what is done with fonts. When embedding of merging is not
+possible you can try to remap the found font onto one on your system. Here are
+some examples:
+
+\starttyping
+graphics.registerpdffont {
+ source = "arial",
+ target = "file:arial.ttf",
+}
+graphics.registerpdffont {
+ source = "arial-bold",
+ target = "file:arialbd.ttf",
+}
+graphics.registerpdffont {
+ source = "arial,bold",
+ target = "file:arialbd.ttf",
+}
+graphics.registerpdffont {
+ source = "helvetica",
+ target = "file:arial.ttf",
+ -- unicode = true,
+}
+graphics.registerpdffont {
+ source = "helvetica-bold",
+ target = "file:arialbd.ttf",
+ -- unicode = true,
+}
+graphics.registerpdffont {
+ source = "courier",
+ target = "file:cour.ttf",
+}
+graphics.registerpdffont {
+ source = "ms-pgothic",
+ unicode = true, -- via unicode (false for composite)
+}
+\stoptyping
+
+The \type {unicode} key needed when you get rubish due to the indices in the page
+stream being different from glyph indices in the used font. In that case we go
+via the \type {tounicode} vector which works ok for the average simple document
+not using special font features. There is some trial and error involved but that
+is probably worth the effort when you have to manipulate many documents.
+
+There are two activities when we compact: fonts and content. When content is
+handled additional parsing of the page stream has to happen. What gets processed
+it determined by the \type {identify} table:
+
+\starttyping
+identify = {
+ content = true,
+ resources = true,
+ page = true,
+}
+\stoptyping
+
+although this is equivalent:
+
+\starttyping
+identify = "all"
+\stoptyping
+
+As a proof of concept we can recolor an included file. Of course this assumes
+a rather simple use of color. Here is an example:
+
+\startbuffer[demo-1]
+\startluacode
+ graphics.registerpdfcompactor ( "preset:demo-1", {
+ identify = {
+ content = true,
+ resources = true,
+ page = true,
+ },
+ merge = {
+ type0 = true,
+ truetype = true,
+ type1 = true,
+ lmtx = true,
+ },
+ recolor = {
+ viagray = { 1, 0, 0 },
+ -- viagray = { 0, 1, 0 },
+ -- viagray = { 0, 1, 0, .5 },
+ -- viagray = { .75 },
+ }
+ } )
+\stopluacode
+\setupexternalfigures[compact=preset:demo-1]
+\startTEXpage
+ \startcombination[3*4]
+ {\externalfigure[test-000.pdf][frame=on]} {\LUAMETATEX\ 0}
+ {\externalfigure[test-001.pdf][frame=on]} {\LUATEX\ 1}
+ {\externalfigure[test-002.pdf][frame=on]} {\LUATEX\ 2}
+ {\externalfigure[test-003.pdf][frame=on,page=1]} {\LUATEX\ 3.1}
+ {\externalfigure[test-003.pdf][frame=on,page=2]} {\LUATEX\ 3.2}
+ {\externalfigure[test-003.pdf][frame=on,page=3]} {\LUATEX\ 3.3}
+ {\externalfigure[test-004.pdf][frame=on,page=1]} {\PDFTEX\ 4.1}
+ {\externalfigure[test-004.pdf][frame=on,page=2]} {\PDFTEX\ 4.2}
+ {\externalfigure[test-004.pdf][frame=on,page=3]} {\PDFTEX\ 4.3}
+ {\externalfigure[test-005.pdf][frame=on,page=1]} {\PDFTEX\ 4.1}
+ {\externalfigure[test-005.pdf][frame=on,page=2]} {\PDFTEX\ 5.2}
+ {\externalfigure[test-005.pdf][frame=on,page=3]} {\PDFTEX\ 5.3}
+ \stopcombination
+\stopTEXpage
+\stopbuffer
+
+\typebuffer[demo-1]
+
+In \in {figure} [fig:compact-1] we make a single page document that embeds 12
+pages from six files made by several engines. The six files have a total of about
+114K but the single page combination is only 19K. The test files are:
+
+\typefile{test-000}
+
+So this one is an \LMTX\ produced file. The next two files:
+
+\typefile{test-001}
+
+and
+
+\typefile{test-002}
+
+are done by \LUATEX\ with \MKIV\ and
+
+\typefile{test-003}
+
+as well as
+
+\typefile{test-004}
+
+and
+
+\typefile{test-005}
+
+are typeset with \PDFTEX\ and \MKII\ so they have the \TYPEONE\ instead of the
+\OPENTYPE\ Latin Modern file embedded (in fact, the \MKII\ and \MKIV\ files use
+the twelve point variant and \LMTX\ the upscaled ten point, so if those were the
+same we would have an even smaller final file.
+
+\startplacefigure[title={An example of content manipulation.},reference=fig:compact-1]
+ \typesetbuffer[demo-1][compact=yes]
+\stopplacefigure
+
+A useful manipulation is removing tags. The fact that the content is tagged
+doesn't mean that tagging has any use, certainly not if it relates to editing
+specific for some application. Maybe at some point I'll add a retagging option
+but for now we just strip:
+
+\starttyping
+strip = {
+ marked = true,
+ -- group = true,
+ -- extgstate = true,
+}
+\stoptyping
+
+The other two are sort of special and might be needed too, especially when for
+instance the states are just there because the producer wasn't clever enough
+to leave them out when not applicable.
+
+It happens that producers use color while actually gray scales are meant. In that
+case one can use these:
+
+\starttyping
+reduce = {
+ color = true, -- both rgb and cmyk
+ rgb = true,
+ cmyk = true,
+}
+\stoptyping
+
+Using a gray scale is more efficient and in the case of \CMYK\ a sloppy \typ {.5
+.5 .5 0 K} quite likely is meant to be \typ {0 0 0 0.5 K} or just \typ {.5 G}.
+
+Remapping \RGB\ to \CMYK\ (or gray if applicable) is done with:
+
+\starttyping
+convert = {
+ rgb = true,
+ -- cmyk = true,
+}
+\stoptyping
+
+and of course one can also remap \CMYK\ to \RGB.
+
+% \setupexternalfigures[compact=preset:mine]
+
+% test \type {test}
+
+% \startTEXpage \externalfigure[test-000.pdf]\stopTEXpage % luametatex
+% \startTEXpage \externalfigure[test-001.pdf]\stopTEXpage % luatex
+% \startTEXpage \externalfigure[test-002.pdf]\stopTEXpage % luatex
+% \dorecurse{3}{
+% \startTEXpage \externalfigure[test-003.pdf][page=#1]\stopTEXpage % luatex
+% }
+% \dorecurse{3}{
+% \startTEXpage \externalfigure[test-004.pdf][page=#1]\stopTEXpage % pdftex
+% }
+% \dorecurse{3}{
+% \startTEXpage \externalfigure[test-005.pdf][page=#1]\stopTEXpage % pdftex
+% }
+
+% -- add = {
+% -- cidset, -- when missing or even fix
+% -- },
+
+I want to stress that manipulating the content stream has some limitations. For
+instance because objects are shared including a page a second time will reuse the
+already converted page. However, you can try the next trick:
+
+\startbuffer[demo-2]
+\startluacode
+ graphics.registerpdfcompactor ( "preset:demo-2", {
+ identify = "all",
+ merge = { lmtx = true },
+ recolor = { viagray = { 0, 1, 0 } },
+ } )
+ graphics.registerpdfcompactor ( "preset:demo-3", {
+ identify = "all",
+ merge = { lmtx = true },
+ recolor = { viagray = { 0, 0, 1 } },
+ } )
+
+\stopluacode
+\setupexternalfigures[compact=preset:demo-1]
+\startTEXpage
+ \startcombination[2*1]
+ {\externalfigure
+ [test-000.pdf]
+ [frame=on,compact=preset:demo-2,width=6cm,object=no,arguments=1]}
+ {demo-2}
+ {\externalfigure
+ [test-000.pdf]
+ [frame=on,compact=preset:demo-3,width=6cm,object=no,arguments=2]}
+ {demo-3}
+ \stopcombination
+\stopTEXpage
+\stopbuffer
+
+\typebuffer[demo-2]
+
+In \in {figure} [fig:compact-2] we see that indeed a different compactor is used.
+We need to disable sharing by setting \type {object} to \type {no}. However, this
+will still share some but we abuse the arguments key to create a different
+sharing hash (normally that key is used to pass arguments to converters).
+
+\startplacefigure[title={An example of manipulation content twice.},reference=fig:compact-2]
+ \typesetbuffer[demo-2][compact=yes]
+\stopplacefigure
+
+I cases where color conversion is problematic (or critical) you can remap
+specific colors. Especially \CMYK\ is sensitive for conversion because there we
+have four color components while in \RGB\ we have only three. Also watching on a
+display (\RGB) is different from looking at a print (\CMYK) and who knows what
+transfer function gets applied in the former. Here is how remapping works:
+
+\starttyping
+local cmykmap = {
+ { 100, 100, 55, 0, 57, 0, 22, 40.8 }
+}
+graphics.registerpdfcompactor ( "preset:demo-5", {
+ identify = "all",
+ merge = { lmtx = true },
+ convert = { cmyk = cmykmap },
+} )
+\stoptyping
+
+Here the entries in a \CMYK\ map are:
+
+\starttyping
+ { factor, c, m, y, k, r, g, b }
+\stoptyping
+
+In this case values are multiplied by 100 which makes sure that we catch rounding
+errors in the \PDF\ definitions. Keep in mind that colors in many applications
+have at most 256 values per component. Also, even quality \LCD\ displays can use
+less than eight bits per component.
+
+\startbuffer[demo-3]
+\startluacode
+ local cmykmap = {
+ { 100, 100, 55, 0, 57, 0, 22, 40.8 } -- factor, c, m, y, k, r, g, b
+ }
+ graphics.registerpdfcompactor ( "preset:demo-4", {
+ identify = "all",
+ merge = { lmtx = true },
+ convert = { cmyk = true },
+ } )
+ graphics.registerpdfcompactor ( "preset:demo-5", {
+ identify = "all",
+ merge = { lmtx = true },
+ convert = { cmyk = cmykmap },
+ } )
+\stopluacode
+\setupexternalfigures[compact=preset:demo-1]
+\startTEXpage
+ \startcombination[2*1]
+ {\externalfigure
+ [test-006.pdf]
+ [frame=on,compact=preset:demo-4,width=6cm,object=no,arguments=3]}
+ {demo-4}
+ {\externalfigure
+ [test-006.pdf]
+ [frame=on,compact=preset:demo-5,width=6cm,object=no,arguments=4]}
+ {demo-5}
+ \stopcombination
+\stopTEXpage
+\stopbuffer
+
+In \in {figure} [fig:compact-3] we show an example. The file used looks like:
+
+\typefile{test-006.tex}
+
+\startplacefigure[title={An example of remapping colors.},reference=fig:compact-3]
+ \typesetbuffer[demo-3][compact=yes]
+\stopplacefigure
+
+I want to stress that you need to check the outcome. Often a visual check is
+enough. Extending the compactor beyond what \MKIV\ provided was to a large extend
+facilitated by a cooperation with Tan, Syabil M. and Ser, Zheng Y. of \quote
+{Team Ramkumar} who did extensive testing and gave enjoyable feedback. In the
+process a test script was made that can help with experiments. We assume that
+\type {qpdf}, \type {mutool} and \type {graphicmagic} abd \type {verapdf} are
+installed.
+
+\starttyping
+mtxrun --script fixpdf --uncompress foo
+mtxrun --script fixpdf --convert --compactor=preset:test foo
+mtxrun --script fixpdf --validate foo
+mtxrun --script fixpdf --check foo
+mtxrun --script fixpdf --compare --resolution=300 foo
+\stoptyping
+
+Here we produce an uncompressed version (so that we can see what we deal with),
+convert the original into a new one, validate (and check the outcome) and create
+a version for visual comparison. It's just an example of usage and here the focus
+was on fixing existing documents (six digit numbers so the workflow needs to be
+carefully checked) and not so much on single page inclusion.
+
+\startlines
+Hans Hagen
+Hasselt NL
+January 2024
+\stoplines
+
+\stopdocument
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
index f759b79b84d..48943407d53 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/primitives/primitives.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/primitives/primitives.tex
@@ -1,9 +1,17 @@
% language=us runpath=texruns:manuals/primitives
+\setupexternalfigures
+ [location={default,global}]
+
+\enableexperiments[fonts.compact]
+\enableexperiments[fonts.accurate]
+% \tracepositions
+
% 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.
+% every few hours. (Picking up writing this manual in 2023 makes me realize how
+% time flies.)
% 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
@@ -13,10 +21,24 @@
%
% Hans Hagen | j.hagen @ xs4all . nl | ntg-context @ ntg . nl
+% iflastnamedcs
+% ignorerest
+
+% \enableexperiments[fonts.compact]
+
+\usemodule[system-syntax]
+\usemodule[system-units]
\usemodule[article-basic]
\usemodule[abbreviations-logos]
\usemodule[scite]
+\setupinteraction
+ [state=start,
+ color=,
+ contrastcolor=,
+ style=,
+ contraststyle=]
+
\definecolor[maincolor][darkblue]
\definecolor[primcolor][darkblue]
\definecolor[nonecolor][darkgray]
@@ -33,13 +55,14 @@
\definehead
[newprimitive]
- [section]
+ [subsection]
[color=maincolor]
\definehead
[oldprimitive]
- [section]
- [color=nonecolor]
+ [subsection]
+ [%color=nonecolor,
+ color=\ifcstok{\structureuservariable{obsolete}}{yes}darkred\else nonecolor\fi]
\setuplist
[newprimitive]
@@ -52,7 +75,13 @@
% We use the next one because we want to check what has been done. In a document
% like this using \type {\foo} makes more sense.
-\protected\def\prm#1{\doifmode{*bodypart}{\index{\tex{#1}}}\tex{#1}}
+\protected\def\prm#1%
+% {\doifmode{*bodypart}{\index{\tex{#1}}}\tex{#1}}
+% {\ifmode{*bodypart}\index{\tex{#1!\string#1!}}\fi\tex{#1}}
+ {\ifmode{*bodypart}\index{\tex{#1}}\fi\tex{#1}}
+
+\protected\def\stx#1%
+ {\ctxlua{moduledata.engine.specification("#1")}} % only for checking
% This is why we need to tag bodymatter.
@@ -88,21 +117,24 @@ 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
+quite some primitives, like those related to \PDFTEX\ specific f(r)ont 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
+explanations out there already. Primitives that relate to typesetting, like those
controlling math, fonts, boxes, attributes, directions, catcodes, \LUA\
-(functions) etc are not discussed here.
+(functions) etc are not discussed or discussed in less detail 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.
+them. We don't go into these details here: it's mostly an overview of what the
+engine provides. If you are new to \TEX, you need to play a while with its mixed
+bag of typesetting and programming features in order to understand the difference
+between this macro language and other languages you might be familiar with.
\startcolumns
\placelist
@@ -115,156 +147,642 @@ In this document the section titles that discuss the \color [nonecolor] {origina
[primcolor] {\LUATEX\ and \LUAMETATEX\ primitives}.
Primitives that extend typesetting related functionality, provide control over
-subsystems (like math), allocate additional datatypes and resources, deal with
-fonts and languages, manipulate boxes and glyphs, etc.\ are not discussed here.
-In this document we concentrate on the programming aspects.
-
-% \startalign[verytolerant,stretch]
-% To be described here: \typ {enforced}, \typ {immutable}, \typ {instance},
-% \typ {aliased}, \typ {mutable}, \typ {overloaded}, \typ {overloadmode}, \typ
-% {tolerant}, \typ {permanent}, \typ {ifflags}, \typ {ifinsert}, \typ
-% {ifmathparameter}, \typ {ifmathstyle}, \typ {ifparameter}, \typ
-% {ifparameters}, \typ {ignorearguments}, \typ {ignorepars}, \typ
-% {parametercount}, \typ {lastchkdim}, \typ {lastchknum}.
-%
-% Of a different order: \typ {adjustspacing}, \typ {adjustspacingshrink}, \typ
-% {adjustspacingstep}, \typ {adjustspacingstretch}, \typ {attribute}, \typ
-% {attributedef}, \typ {automaticdiscretionary}, \typ {automatichyphenpenalty},
-% \typ {automigrationmode}, \typ {boundary}, \typ {boxattribute}, \typ
-% {boxdirection}, \typ {boxorientation}, \typ {boxtotal}, \typ {boxxmove}, \typ
-% {boxxoffset}, \typ {boxymove}, \typ {boxyoffset}, \typ {catcodetable}, \typ
-% {clearmarks}, \typ {crampeddisplaystyle}, \typ {crampedscriptscriptstyle}, \typ
-% {crampedscriptstyle}, \typ {crampedtextstyle}, \typ {directlua}, \typ {efcode},
-% \typ {everybeforepar}, \typ {everytab}, \typ {exceptionpenalty}, \typ
-% {explicitdiscretionary}, \typ {explicithyphenpenalty}, \typ {firstvalidlanguage},
-% \typ {fontid}, \typ {fontmathcontrol}, \typ {fontspecifiedsize}, \typ
-% {fonttextcontrol}, \typ {formatname}, \typ {gleaders}, \typ {gluespecdef}, \typ
-% {glyphdatafield}, \typ {glyphoptions}, \typ {glyphscale}, \typ
-% {glyphscriptfield}, \typ {glyphscriptscale}, \typ {glyphscriptscriptscale}, \typ
-% {glyphstatefield}, \typ {glyphtextscale}, \typ {glyphxoffset}, \typ
-% {glyphxscale}, \typ {glyphyoffset}, \typ {glyphyscale}, \typ {hccode}, \typ
-% {hjcode}, \typ {hpack}, \typ {hyphenationmin}, \typ {hyphenationmode}, \typ
-% {initcatcodetable}, \typ {insertbox},\typ {insertcopy}, \typ {insertdepth}, \typ
-% {insertdistance}, \typ {insertheight}, \typ {insertheights}, \typ {insertlimit},
-% \typ {insertmode}, \typ {insertmultiplier}, \typ {insertprogress}, \typ
-% {insertunbox}, \typ {insertuncopy}, \typ {insertwidth}, \typ {lastnodesubtype},
-% \typ {leftmarginkern}, \typ {letcharcode}, \typ {linedirection}, \typ {linepar},
-% \typ {localbrokenpenalty}, \typ {localinterlinepenalty}, \typ {lpcode}, \typ
-% {luabytecode}, \typ {luabytecodecall}, \typ {luacopyinputnodes}, \typ {luadef},
-% \typ {luaescapestring}, \typ {luafunction}, \typ {luafunctioncall}, \typ
-% {luatexbanner}, \typ {luatexrevision}, \typ {luatexversion}, \typ
-% {mathcontrolmode}, \typ {mathdelimitersmode}, \typ {mathdirection}, \typ
-% {mathdisplayskipmode}, \typ {matheqnogapstep}, \typ {mathflattenmode}, \typ
-% {mathfontcontrol}, \typ {mathitalicsmode}, \typ {mathnolimitsmode}, \typ
-% {mathpenaltiesmode}, \typ {mathrulesfam}, \typ {mathrulesmode}, \typ
-% {mathrulethicknessmode}, \typ {mathscale}, \typ {mathscriptboxmode}, \typ
-% {mathscriptcharmode}, \typ {mathscriptsmode}, \typ {mathstyle}, \typ
-% {mathsurroundmode}, \typ {mathsurroundskip}, \typ {mugluespecdef}, \typ
-% {noaligned}, \typ {noboundary}, \typ {nohrule}, \typ {normalizelinemode}, \typ
-% {nospaces}, \typ {novrule}, \typ {numericscale}, \typ {numexpression}, \typ
-% {outputbox}, \typ {parattribute}, \typ {pardirection}, \typ {postexhyphenchar},
-% \typ {posthyphenchar}, \typ {prebinoppenalty}, \typ {predisplaygapfactor}, \typ
-% {preexhyphenchar}, \typ {prehyphenchar}, \typ {prerelpenalty}, \typ
-% {protrudechars}, \typ {protrusionboundary}, \typ {pxdimen}, \typ {quitvmode},
-% \typ {retokenize}, \typ {rightmarginkern}, \typ {rpcode}, \typ
-% {savecatcodetable}, \typ {scantextokens}, \typ {semiexpanded}, \typ {setfontid},
-% \typ {snapshotpar}, \typ {supmarkmode}, \typ {textdirection}, \typ
-% {thewithoutunit}, \typ {tpack}, \typ {tracingexpressions}, \typ {tracingfonts},
-% \typ {tracinghyphenation}, \typ {tracingmath}, \typ {undent}, \typ {vpack}, \typ
-% {wordboundary}, \typ {wrapuppar}.
-% \stopalign
-%
+subsystems (like math), allocate additional data types and resources, deal with
+fonts and languages, manipulate boxes and glyphs, etc.\ are hardly discussed
+here, only mentioned. Math for instance is a topic of its own. In this document
+we concentrate on the programming aspects.
+
+Most of the new primitives are discussed in specific manuals and often also
+original primitives are covered there but the best explanations of the
+traditional primitives can be found in The \TEX book by Donald Knuth and \TEX\ by
+Topic from Victor Eijkhout. I see no need to try to improve on those.
+
% {\em Some new primitives in this list might be forgotten or already became
% obsolete. Let me know if you run into one.}
\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={\prm {meaning}}]
+\startsubject[title=Primitives]
-We start with a primitive that will be used in the following sections. The
-reported meaning can look a bit different than the one reported by other engines
-which is a side effect of additional properties and more extensive argument
-parsing.
+\startoldprimitive[title={\prm {<space>}}]
-\startbuffer
-\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaning\foo
-\stopbuffer
+This original \TEX\ primitive is equivalent to the more verbose \prm
+{explicitspace}.
-\typebuffer \getbuffer
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {-}}]
+
+This original \TEX\ primitive is equivalent to the more verbose \prm
+{explicitdiscretionary}.
\stopoldprimitive
-\startnewprimitive[title={\prm {meaningless}}]
+\startoldprimitive[title={\prm {/}}]
-This one reports a bit less than \prm {meaning}.
+This original \TEX\ primitive is equivalent to the more verbose \prm
+{explicititaliccorrection}.
-\startbuffer
-\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningless\foo
-\stopbuffer
+\stopoldprimitive
-\typebuffer \getbuffer
+% \startnewprimitive[title={\prm {Uabove}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uabovewithdelims}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uatop}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uatopwithdelims}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Udelcode}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Udelimited}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Udelimiter}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Udelimiterover}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Udelimiterunder}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uhextensible}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uleft}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccent}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccentbasedepth}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccentbaseheight}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccentbottomovershoot}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccentbottomshiftdown}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccentextendmargin}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccentsuperscriptdrop}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccentsuperscriptpercent}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccenttopovershoot}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccenttopshiftup}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaccentvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathadapttoleft}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathadapttoright}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathaxis}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathbottomaccentvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathchar}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathchardef}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathcode}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathconnectoroverlapmin}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathdegreevariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathdelimiterextendmargin}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathdelimiterovervariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathdelimiterpercent}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathdelimitershortfall}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathdelimiterundervariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathdenominatorvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathdictdef}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathexheight}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathextrasubpreshift}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathextrasubprespace}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathextrasubshift}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathextrasubspace}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathextrasuppreshift}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathextrasupprespace}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathextrasupshift}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathextrasupspace}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathflattenedaccentbasedepth}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathflattenedaccentbaseheight}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathflattenedaccentbottomshiftdown}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathflattenedaccenttopshiftup}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathfractiondelsize}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathfractiondenomdown}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathfractiondenomvgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathfractionnumup}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathfractionnumvgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathfractionrule}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathfractionvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathhextensiblevariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathlimitabovebgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathlimitabovekern}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathlimitabovevgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathlimitbelowbgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathlimitbelowkern}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathlimitbelowvgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathlimits}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathnoaxis}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathnolimits}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathnolimitsubfactor}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathnolimitsupfactor}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathnumeratorvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathopenupdepth}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathopenupheight}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathoperatorsize}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathoverbarkern}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathoverbarrule}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathoverbarvgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathoverdelimiterbgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathoverdelimitervariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathoverdelimitervgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathoverlayaccentvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathoverlinevariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathphantom}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathpresubshiftdistance}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathpresupshiftdistance}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathprimeraise}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathprimeraisecomposed}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathprimeshiftdrop}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathprimeshiftup}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathprimespaceafter}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathprimevariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathprimewidth}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathquad}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathradicaldegreeafter}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathradicaldegreebefore}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathradicaldegreeraise}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathradicalextensibleafter}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathradicalextensiblebefore}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathradicalkern}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathradicalrule}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathradicalvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathradicalvgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathruledepth}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathruleheight}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathskeweddelimitertolerance}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathskewedfractionhgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathskewedfractionvgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsource}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathspaceafterscript}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathspacebeforescript}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathspacebetweenscript}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathstackdenomdown}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathstacknumup}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathstackvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathstackvgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsubscriptsnap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsubscriptvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsubshiftdistance}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsubshiftdown}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsubshiftdrop}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsubsupshiftdown}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsubsupvgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsubtopmax}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsupbottommin}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsuperscriptsnap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsuperscriptvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsupshiftdistance}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsupshiftdrop}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsupshiftup}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathsupsubbottommax}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathtopaccentvariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathunderbarkern}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathunderbarrule}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathunderbarvgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathunderdelimiterbgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathunderdelimitervariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathunderdelimitervgap}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathunderlinevariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathuseaxis}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathvextensiblevariant}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathvoid}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathxscale}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umathyscale}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Umiddle}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uoperator}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uover}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uoverdelimiter}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uoverwithdelims}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uradical}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uright}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uroot}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Urooted}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uskewed}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uskewedwithdelims}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Ustartdisplaymath}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Ustartmath}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Ustartmathmode}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Ustopdisplaymath}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Ustopmath}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Ustopmathmode}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Ustretched}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Ustretchedwithdelims}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uunderdelimiter}}]
+% \stopnewprimitive
+
+% \startnewprimitive[title={\prm {Uvextensible}}]
+% \stopnewprimitive
+
+\startoldprimitive[title={\prm {above}}][obsolete=yes]
+
+This is a variant of \prm {over} that doesn't put a rule in between.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {abovedisplayshortskip}}]
+
+The glue injected before a display formula when the line above it is not
+overlapping with the formula. Watch out for interference with \prm
+{baselineskip}. It can be controlled by \prm {displayskipmode}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {abovedisplayskip}}]
+
+The glue injected before a display formula. Watch out for interference with
+\prm {baselineskip}. It can be controlled by \prm {displayskipmode}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {abovewithdelims}}][obsolete=yes]
+
+This is a variant of \prm {atop} but with delimiters. It has a more advanced
+upgrade in \prm {Uabovewithdelims}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {accent}}][obsolete=yes]
+
+This primitive is kind of obsolete in wide engines and takes two arguments: the
+indexes of an accent and a base character.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {additionalpageskip}}]
+
+This quantity will be added to the current page goal, stretch and shrink after
+which it will be set to zero.
\stopnewprimitive
-\startnewprimitive[title={\prm {meaningfull}}]
+\startoldprimitive[title={\prm {adjdemerits}}]
-This one reports a bit more than \prm {meaning}.
+When \TEX\ considers to lines to be incompatible it will add this penalty to its
+verdict when considering this breakpoint.
-\startbuffer
-\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningfull\foo
-\stopbuffer
+\stopoldprimitive
-\typebuffer \getbuffer
+\startnewprimitive[title={\prm {adjustspacing}}]
+
+This parameter controls expansion (hz). A value~2 expands glyphs and font kerns
+and a value of~3 only glyphs. Expansion of kerns can have side effects when they
+are used for positioning by \OPENTYPE\ features.
\stopnewprimitive
-\startnewprimitive[title={\prm {meaningasis}}]
+\startnewprimitive[title={\prm {adjustspacingshrink}}]
-Although it is not really round trip with the original due to information
-being lost this primitive tries to return an equivalent definition.
+When set to a non zero value this overloads the shrink maximum in a font when
+expansion is applied. This is then the case for all fonts.
-\startbuffer
-\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningasis\foo
-\stopbuffer
+\stopnewprimitive
-\typebuffer \getbuffer
+\startnewprimitive[title={\prm {adjustspacingstep}}]
+
+When set to a non zero value this overloads the expansion step in a font when
+expansion is applied. This is then the case for all fonts.
\stopnewprimitive
-% \startoldprimitive[title={\prm {par}}]
-% \stopoldprimitive
-%
-% \startoldprimitive[title={\prm {linepar}}]
-% \stopoldprimitive
+\startnewprimitive[title={\prm {adjustspacingstretch}}]
-\startoldprimitive[title={\prm {afterassignment}}]
+When set to a non zero value this overloads the stretch maximum in a font when
+expansion is applied. This is then the case for all fonts.
-The token following \prm {afterassignment}, a traditional \TEX\ primitive, is
-saved and gets injected (and then expanded) after a following assignment took
-place.
+\stopnewprimitive
-\startbuffer
-\afterassignment !\def\MyMacro {}\quad
-\afterassignment !\let\MyMacro ?\quad
-\afterassignment !\scratchcounter 123\quad
-\afterassignment !%
-\afterassignment ?\advance\scratchcounter by 1
-\stopbuffer
+\startoldprimitive[title={\prm {advance}}]
-\typebuffer
+Advances the given register by an also given value:
-The \prm {afterassignment}s are not accumulated, the last one wins:
+\starttyping
+\advance\scratchdimen 10pt
+\advance\scratchdimen by 3pt
+\advance\scratchcounterone \zerocount
+\advance\scratchcounterone \scratchcountertwo
+\stoptyping
-{\getbuffer}
+The \type {by} keyword is optional.
\stopoldprimitive
+\startnewprimitive[title={\prm {advanceby}}]
+
+This is slightly more efficient variant of \prm {advance} that doesn't look for
+\type {by} and therefore, if one is missing, doesn't need to push back the last
+seen token. Using \prm {advance} with \type {by} is nearly as efficient but takes
+more tokens.
+
+\stopnewprimitive
+
\startnewprimitive[title={\prm {afterassigned}}]
The \prm {afterassignment} primitive stores a token to be injected (and thereby
@@ -285,6 +803,28 @@ results in: \inlinebuffer\ being typeset.
\stopnewprimitive
+\startoldprimitive[title={\prm {afterassignment}}]
+
+The token following \prm {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 \prm {afterassignment}s are not accumulated, the last one wins:
+
+{\getbuffer}
+
+\stopoldprimitive
+
\startoldprimitive[title={\prm {aftergroup}}]
The traditional \TEX\ \prm {aftergroup} primitive stores the next token and
@@ -325,6 +865,235 @@ Because it happens after the group, we're no longer typesetting in bold.
\stopnewprimitive
+\startnewprimitive[title={\prm {aliased}}]
+
+This primitive is part of the overload protection subsystem where control sequences
+can be tagged.
+
+\startbuffer
+\permanent\def\foo{FOO}
+ \let\ofo\foo
+\aliased \let\oof\foo
+
+\meaningasis\foo
+\meaningasis\ofo
+\meaningasis\oof
+\stopbuffer
+
+\typebuffer
+
+gives:
+
+\startlines \tt
+\getbuffer
+\stoplines
+
+When a something is \prm {let} the \quote {permanent}, \quote {primitive} and
+\quote {immutable} flags are removed but the \prm {aliased} prefix retains
+them.
+
+\startbuffer
+\let\relaxed\relax
+
+\meaningasis\relax
+\meaningasis\relaxed
+\stopbuffer
+
+\typebuffer
+
+So in this example the \type {\relaxed} alias is not flagged as primitive:
+
+\startlines \tt
+\getbuffer
+\stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {aligncontent}}]
+
+This is equivalent to a hash in an alignment preamble. Contrary to \prm
+{alignmark} there is no need to duplicate inside a macro definition.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {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={\prm {alignmentcellsource}}]
+
+This sets the source id (a box property) of the current alignment cell.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {alignmentwrapsource}}]
+
+This sets the source id (a box property) of the current alignment row (in a \prm
+{halign}) or column (in a \prm {valign}).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {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
+
+\startnewprimitive[title={\prm {allcrampedstyles}}]
+
+A symbolic representation of \prm {crampeddisplaystyle}, \prm {crampedtextstyle},
+\prm {crampedscriptstyle} and \prm {crampedscriptscriptstyle}; integer
+representation: \the\allcrampedstyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {alldisplaystyles}}]
+
+A symbolic representation of \prm {displaystyle} and \prm {crampeddisplaystyle};
+integer representation: \the\alldisplaystyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {allmainstyles}}]
+
+A symbolic representation of \prm {displaystyle}, \prm {crampeddisplaystyle},
+\prm {textstyle} and \prm {crampedtextstyle}; integer representation:
+\the\allmainstyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {allmathstyles}}]
+
+A symbolic representation of \prm {displaystyle}, \prm {crampeddisplaystyle},
+\prm {textstyle}, \prm {crampedtextstyle}, \prm {scriptstyle}, \prm
+{crampedscriptstyle}, \prm {scriptscriptstyle} and \prm
+{crampedscriptscriptstyle}; integer representation: \the\allmathstyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {allscriptscriptstyles}}]
+
+A symbolic representation of \prm {scriptscriptstyle} and \prm
+{crampedscriptscriptstyle}; integer representation: \the\allscriptscriptstyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {allscriptstyles}}]
+
+A symbolic representation of \prm {scriptstyle} and \prm {crampedscriptstyle};
+integer representation: \the\allscriptstyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {allsplitstyles}}]
+
+A symbolic representation of \prm {displaystyle} and \prm {textstyle} but not
+\prm {scriptstyle} and \prm {scriptscriptstyle}: set versus reset; integer
+representation: \the\allsplitstyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {alltextstyles}}]
+
+A symbolic representation of \prm {textstyle} and \prm {crampedtextstyle};
+integer representation: \the\alltextstyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {alluncrampedstyles}}]
+
+A symbolic representation of \prm {displaystyle}, \prm {textstyle}, \prm
+{scriptstyle} and \prm {scriptscriptstyle}; integer representation:
+\the\alluncrampedstyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {allunsplitstyles}}]
+
+A symbolic representation of \prm {scriptstyle} and \prm {scriptscriptstyle}; integer
+representation: \the\allunsplitstyles.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {amcode}}]
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {associateunit}}]
+
+The \TEX\ engine comes with some build in units, like \type {pt} (fixed) and
+\type {em} (adaptive). On top of that a macro package can add additional units, which is
+what we do in \CONTEXT. In \in {figure} [fig:units] we show the current repertoire.
+
+\startplacefigure[title=Available units,reference=fig:units]
+ \showunitsmap[tight]
+ \showunitsmaplegend
+\stopplacefigure
+
+When this primitive is used in a context where a number is expected it returns the origin
+of the unit (in the color legend running from 1 upto 4). A new unit is defined as:
+
+\starttyping
+\newdimen\MyDimenZA \MyDimenZA=10pt
+
+\protected\def\MyDimenAB{\dimexpr\hsize/2\relax}
+
+\associateunit za \MyDimenZA
+\associateunit zb \MyMacroZB
+\stoptyping
+
+Possible associations are: macros that expand to a dimension, internal dimension
+registers, register dimensions (\prm {dimendef}, direct dimensions (\prm
+{dimensiondef}) and \LUA\ functions that return a dimension.
+
+One can run into scanning ahead issues where \TEX\ expects a unit and a user unit
+gets expanded. This is why for instance in \CONTEXT\ we define the \type{ma} unit
+as:
+
+\starttyping
+\protected\def\mathaxisunit{\scaledmathaxis\mathstyle\norelax}
+
+\associateunit ma \mathaxisunit % or \newuserunit \mathaxisunit ma
+\stoptyping
+
+So that it can be used in rule specifications that themselves look ahead for
+keywords and therefore are normally terminated by a \prm {relax}. Adding the
+extra \prm {norelax} will make the scanner see one that doesn't get fed back into
+the input. Of course a macro package has to manage extra units in order to avoid
+conflicts.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {atendoffile}}]
+
+The \prm {everyeof} primitive is kind of useless because you don't know if a file
+(which can be a tokenlist processed as pseudo file) itself includes a file, which
+then results in nested application of this token register. One way around this is:
+
+\startbuffer
+\atendoffile\SomeCommand
+\stopbuffer
+
+\typebuffer
+
+This acts on files the same way as \prm {atendofgroup} does. Multiple calls will
+be accumulated and are bound to the current file.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {atendoffiled}}]
+
+This is the multi token variant of \prm {atendoffile}. Multiple invocations are
+accumulated and by default prepended to the existing list. As with grouping this
+permits proper nesting. You can force an append by the optional keyword {reverse}.
+
+\stopnewprimitive
+
\startnewprimitive[title={\prm {atendofgroup}}]
The token provided will be injected just before the group ends. Because
@@ -367,92 +1136,931 @@ Multiple invocations are accumulated: {\inlinebuffer}.
\stopnewprimitive
-\startnewprimitive[title={\prm {toksapp}}]
+\startoldprimitive[title={\prm {atop}}][obsolete=yes]
-One way to append something to a token list is the following:
+This one stack two math elements on top of each other, like a fraction but with
+no rule. It has a more advanced upgrade in \prm {Uatop}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {atopwithdelims}}][obsolete=yes]
+
+This is a variant of \prm {atop} but with delimiters. It has a more advanced
+upgrade in \prm {Uatopwithdelims}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {attribute}}]
+
+The following sets an attribute(register) value:
\starttyping
-\scratchtoks\expandafter{\the\scratchtoks more stuff}
+\attribute 999 = 123
\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:
+An attribute is unset by assigning \the \attributeunsetvalue\ to it. A user needs
+to be aware of attributes being used now and in the future of a macro package and
+setting them this way is very likely going to interfere.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {attributedef}}]
+
+This primitive can be used to relate a control sequence to an attribute register
+and can be used to implement a mechanism for defining unique ones that won't
+interfere. As with other registers: leave management to the macro package in
+order to avoid unwanted side effects!
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {automaticdiscretionary}}]
+
+This is an alias for the automatic hyphen trigger \type {-}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {automatichyphenpenalty}}]
+
+The penalty injected after an automatic discretionary \type {-}, when \prm
+{hyphenationmode} enables this.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {automigrationmode}}]
+
+This bitset determines what will bubble up to an outer level:
+
+\getbuffer[engine:syntax:automigrationcodes]
+
+The current value is {\tttf 0x\tohexadecimal\automigrationmode}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {autoparagraphmode}}]
+
+A paragraph can be triggered by an empty line, a \prm {par} token or an
+equivalent of it. This parameter controls how \type {\par} is interpreted in
+different scenarios:
+
+\getbuffer[engine:syntax:autoparagraphcodes]
+
+The current value is {\tttf 0x\tohexadecimal\autoparagraphmode} and setting it to
+a non|-|zero value can have consequences for mechanisms that expect otherwise.
+The text option uses the same code as an empty line. The macro option checks a
+token in a macro preamble against the frozen \prm {\par} token. The last option
+ignores the par token.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {badness}}]
+
+This one returns the last encountered badness value.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {baselineskip}}]
+
+This is the maximum glue put between lines. The depth of the previous and height
+of the next line are substracted.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {batchmode}}]
+
+This command disables (error) messages which can safe some runtime in situations
+where \TEX's character|-|by|-|character log output impacts runtime. It only makes
+sense in automated workflows where one doesn't look at the log anyway.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {begincsname}}]
+
+The next code creates a control sequence token from the given serialized tokens:
\starttyping
-\toksapp\scratchtoks{more stuff}
-\toksapp\scratchtoksone\scratchtokstwo
+\csname mymacro\endcsname
\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.
+When \type {\mymacro} is not defined a control sequence will be created with the
+meaning \prm {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={\prm {etoksapp}}]
+\startoldprimitive[title={\prm {begingroup}}]
-A variant of \prm {toksapp} is the following: it expands the to be appended
-content.
+This primitive starts a group and has to be ended with \prm {endgroup}. See \prm
+{beginsimplegroup} for more info.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {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 \prm
+{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={\prm {beginmathgroup}}]
+
+In math mode grouping with \prm {begingroup} and \prm {endgroup} in some cases
+works as expected, but because the math input is converted in a list that gets
+processed later some settings can become persistent, like changes in style or
+family. The engine therefore provides the alternatives \prm {beginmathgroup} and
+\prm {endmathgroup} that restore some properties.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {beginsimplegroup}}]
+
+The original \TEX\ engine distinguishes two kind of grouping that at the user end
+show up as:
\starttyping
-\def\temp{more stuff}
-\etoksapp\scratchtoks{some \temp}
+\begingroup \endgroup
+\bgroup \egroup { }
\stoptyping
+where the last two pairs are equivalent unless the scanner explicitly wants to see a
+left and|/|or right brace and not an equivalent. For the sake of simplify we use
+the aliases here. It is not possible to mix these pairs, so:
+
+\starttyping
+\bgroup xxx\endgroup
+\begingroup xxx\egroup
+\stoptyping
+
+will in both cases issue an error. This can make it somewhat hard to write generic
+grouping macros without somewhat dirty trickery. The way out is to use the generic
+group opener \prm {beginsimplegroup}.
+
+Internally \LUAMETATEX\ is aware of what group it currently is dealing with and
+there we distinguish:
+
+\starttabulate[||||]
+\NC simple group \NC \type {\bgroup} \NC \type {\egroup} \NC \NR
+\NC semi simple group \NC \type {\begingroup} \NC \type {\endgroup} \type {\endsimplegroup} \NC \NR
+\NC also simple group \NC \type {\beginsimplegroup} \NC \type {\egroup} \type {\endgroup} \type {\endsimplegroup} \NC \NR
+\NC math simple group \NC \type {\beginmathgroup} \NC \type {\endmathgroup} \NC \NR
+\stoptabulate
+
+This means that you can say:
+
+\starttyping
+\beginsimplegroup xxx\endsimplegroup
+\beginsimplegroup xxx\endgroup
+\beginsimplegroup xxx\egroup
+\stoptyping
+
+So a group started with \prm {beginsimplegroup} can be finished in three ways
+which means that the user (or calling macro) doesn't have take into account what
+kind of grouping was used to start with. Normally usage of this primitive is
+hidden in macros and not something the user has to be aware of.
+
\stopnewprimitive
-\startnewprimitive[title={\prm {tokspre}}]
+\startoldprimitive[title={\prm {belowdisplayshortskip}}]
-Where appending something is easy because of the possible \prm {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.
+The glue injected aftter a display formula when the line above it is not
+overlapping with the formula (\TEX\ can't look ahead). Watch out for interference
+with \prm {baselineskip}. It can be controlled by \prm {displayskipmode}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {belowdisplayskip}}]
+
+The glue injected after a display formula. Watch out for interference with \prm
+{baselineskip}. It can be controlled by \prm {displayskipmode}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {binoppenalty}}][obsolete=yes]
+
+This internal quantity is a compatibility feature because normally we will use
+the inter atom spacing variables.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {botmark}}][obsolete=yes]
+
+This is a reference to the last mark on the current page, it gives back tokens.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {botmarks}}]
+
+This is a reference to the last mark with the given id (a number) on the current
+page, it gives back tokens.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {boundary}}]
+
+Boundaries are signals added to he current list. This primitive injects a user
+boundary with the given (integer) value. Such a boundary can be consulted at the
+\LUA\ end or with \prm {lastboundary}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {box}}]
+
+This is the box register accessor. While other registers have one property a box
+has many, like \prm {wd}, \prm {ht} and \prm {dp}. This primitive returns the box
+and resets the register.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {boxadapt}}]
+
+Adapting will recalculate the dimensions with a scale factor for the glue:
+
+\startbuffer
+\setbox 0 \hbox {test test test}
+\setbox 2 \hbox {\red test test test} \boxadapt 0 200
+\setbox 4 \hbox {\blue test test test} \boxadapt 0 -200
+\ruledhbox{\box0} \vskip-\lineheight
+\ruledhbox{\box0} \vskip-\lineheight
+\ruledhbox{\box0}
+\stopbuffer
+
+\typebuffer
+
+Like \prm {boxfreeze} and \prm {boxrepack} this primitive has been introduced for
+experimental usage, although we do use some in production code.
+
+\getbuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxanchor}}]
+
+This feature is part of an (experimental) mechanism that relates boxes. The
+engine just tags a box and it is up to the macro package to deal with it.
+
+\startbuffer
+\setbox0\hbox anchor "01010202 {test}\tohexadecimal\boxanchor0
+\stopbuffer
+
+\typebuffer
+
+This gives: \inlinebuffer. Of course this feature is very macro specific and
+should not be used across macro packages without coordination. An anchor has
+two parts each not exceeding \type {0x0FFF}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxanchors}}]
+
+This feature is part of an (experimental) mechanism that relates boxes. The
+engine just tags a box and it is up to the macro package to deal with it.
+
+\startbuffer
+\setbox0\hbox anchors "0101 "0202 {test}\tohexadecimal\boxanchors0
+\stopbuffer
+
+\typebuffer
+
+This gives: \inlinebuffer. Of course this feature is very macro specific and
+should not be used across macro packages without coordination. An anchor has
+two parts each not exceeding \type {0x0FFF}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxattribute}}]
+
+Every node, and therefore also every box gets the attributes set that are
+active at the moment of creation. Additional attributes can be set too:
+
+\startbuffer
+\darkred
+\setbox0\hbox attr 9999 1 {whatever}
+\the\boxattribute 0 \colorattribute
+\the\boxattribute 0 9998
+\the\boxattribute 0 9999
+\stopbuffer
+
+\typebuffer
+
+A macro package should make provide a way define attributes that don't clash the
+ones it needs itself, like, in \CONTEXT, the ones that can set a color
+
+\startlines \getbuffer \stoplines
+
+The number \the\attributeunsetvalue\ (\tohexadecimal\attributeunsetvalue)
+indicates an unset attribute.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxdirection}}]
+
+The direction of a box defaults to \type {l2r} but can be explicitly set:
+
+\startbuffer
+\setbox0\hbox direction 1 {this is a test}\textdirection1
+\setbox2\hbox direction 0 {this is a test}\textdirection0
+\the\boxdirection0: \box0
+\the\boxdirection2: \box2
+\stopbuffer
+
+\typebuffer
+
+The \prm {textdirection} does not influence the box direction:
+
+\startlines \getbuffer \stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxfinalize}}]
+
+This is special version of \prm {boxfreeze} which we demonstrate
+with an example:
+
+\startbuffer[setthem]
+\setbox0\ruledvbox to 3cm{\hsize 2cm test\vskip10pt plus 10pt test}
+\setbox2\copy0\setbox4\copy0\setbox6\copy0\setbox8\copy0
+\stopbuffer
+
+\startbuffer[usethem]
+\boxlimitate 0 0 % don't recurse
+\boxfreeze 2 0 % don't recurse
+\boxfinalize 4 500 % scale glue multiplier by .50
+\boxfinalize 6 250 % scale glue multiplier by .25
+\boxfinalize 8 100 % scale glue multiplier by .10
+
+\hpack\bgroup
+ \copy0\quad\copy2\quad\copy4\quad\copy6\quad\copy8
+\egroup
+\stopbuffer
+
+\typebuffer[usethem]
+
+where the boxes are populated with:
+
+\typebuffer[setthem]
+
+\startlinecorrection
+\getbuffer[setthem,usethem]
+\stoplinecorrection
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxfreeze}}]
+
+Glue in a box has a fixed component that will always be used and stretch and
+shrink that kicks in when needed. The effective value (width) of the glue is
+driven by some box parameters that are set by the packaging routine. This is why
+we can unbox: the original value is kept. It is the backend that calculates the
+effective value. Te \prm {boxfreeze} primitive can do the same: turn the flexible
+glue into a fixed one.
+
+\startbuffer
+\setbox 0 \hbox to 6cm {\hss frost}
+\setbox 2 \hbox to 6cm {\hss frost}
+\boxfreeze 2 0
+\ruledhbox{\unhbox 0}
+\ruledhbox{\unhbox 2}
+\stopbuffer
+
+\typebuffer
+
+The second parameter to \prm {boxfreeze} determines recursion. We don't recurse
+here so just freeze the outer level:
+
+\getbuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxgeometry}}]
+
+A box can have an orientation, offsets and|/|or anchors. These are stored
+independently but for efficiency reasons we register if one or more of these
+properties is set. This primitive accesses this state; it is a bitset:
+
+\getbuffer[engine:syntax:listgeometrycodes]
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxlimit}}]
+
+This primitive will freeze the glue in a box but only when there is glue marked
+with the limit option.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxlimitate}}]
+
+This primitive will freeze the glue in a box. It takes two arguments, a box
+number and an number that when set to non|-|zero will recurse into nested lists.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxlimitmode}}]
+
+This variable controls if boxes with glue marked \quote {limit} will be checked
+and frozen.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {boxmaxdepth}}]
+
+You can limit the depth of boxes being constructed. It's one of these parameters
+that should be used with care because when that box is filled nested boxes can be
+influenced.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {boxorientation}}]
+
+The orientation field can take quite some values and is discussed in one of the low level
+\CONTEXT\ manuals. Some properties are dealt with in the \TEX\ engine because they
+influence dimensions but in the end it is the backend that does the work.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxrepack}}]
+
+When a box of to wide or tight we can tweak it a bit with this primitive. The
+primitive expects a box register and a dimension, where a positive number adds
+and a negatie subtracts from the current box with.
+
+\startbuffer
+\setbox 0 \hbox {test test test}
+\setbox 2 \hbox {\red test test test} \boxrepack0 +.2em
+\setbox 4 \hbox {\green test test test} \boxrepack0 -.2em
+\ruledhbox{\box0} \vskip-\lineheight
+\ruledhbox{\box0} \vskip-\lineheight
+\ruledhbox{\box0}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We can also use this primitive to check the natural dimensions of a box:
+
+\startbuffer
+\setbox 0 \hbox spread 10pt {test test test}
+\ruledhbox{\box0} (\the\boxrepack0,\the\wd0)
+\stopbuffer
+
+\typebuffer
+
+In this context only one argument is expected.
+
+\getbuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxshift}}]
+
+Returns or sets how much the box is shifted: up or down in horizontally mode, left or
+right in vertical mode.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxshrink}}]
+
+Returns the amount of shrink found (applied) in a box:
+
+\startbuffer
+\setbox0\hbox to 4em {m m m m}
+\the\boxshrink0
+\stopbuffer
+
+\typebuffer
+
+gives: \inlinebuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxsource}}]
+
+This feature is part of an (experimental) mechanism that relates boxes. The
+engine just tags a box and it is up to the macro package to deal with it.
+
+\startbuffer
+\setbox0\hbox source 123 {m m m m}
+\the\boxsource0
+\stopbuffer
+
+\typebuffer
+
+This gives: \inlinebuffer. Of course this feature is very macro specific and
+should not be used across macro packages without coordination.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxstretch}}]
+
+Returns the amount of stretch found (applied) in a box:
+
+\startbuffer
+\setbox0\hbox to 6em {m m m m}
+\the\boxstretch0
+\stopbuffer
+
+\typebuffer
+
+gives: \inlinebuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxtarget}}]
+
+This feature is part of an (experimental) mechanism that relates boxes. The
+engine just tags a box and it is up to the macro package to deal with it.
+
+\startbuffer
+\setbox0\hbox source 123 {m m m m}
+\the\boxsource0
+\stopbuffer
+
+\typebuffer
+
+This gives: \inlinebuffer. Of course this feature is very macro specific and
+should not be used across macro packages without coordination.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxtotal}}]
+
+Returns the total of height and depth of the given box.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxvadjust}}]
+
+When used as query this returns a bitset indicating the associated adjust and
+migration (marks and inserts) data:
+
+\starttabulate[|T|l|]
+\NC 0x1 \NC pre adjusted \NC \NR
+\NC 0x2 \NC post adjusted \NC \NR
+\NC 0x4 \NC pre migrated \NC \NR
+\NC 0x8 \NC post migrated \NC \NR
+\stoptabulate\
+
+When used as a setter it directly adds adjust data to the box and it accepts the
+same keywords as \prm {vadjust}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxxmove}}]
+
+This will set the vertical offset and adapt the dimensions accordingly.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxxoffset}}]
+
+Returns or sets the horizontal offset of the given box.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxymove}}]
+
+This will set the vertical offset and adapt the dimensions accordingly.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {boxyoffset}}]
+
+Returns or sets the vertical offset of the given box.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {brokenpenalty}}]
+
+This penalty is added after a line that ends with a hyphen; it can help to
+discourage a page break (or split in a box).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {catcode}}]
+
+Every character can be put in a category, but this is typically
+something that the macro package manages because changes can affect
+behavior. Also, once passed as an argument, the catcode of a character
+is frozen. There are 16 different values:
+
+\starttabulate[|l|c|l|c|]
+\NC \type {\escapecatcode } \NC \the\escapecatcode
+\NC \type {\begingroupcatcode } \NC \the\begingroupcatcode \NC \NR
+\NC \type {\endgroupcatcode } \NC \the\endgroupcatcode
+\NC \type {\mathshiftcatcode } \NC \the\mathshiftcatcode \NC \NR
+\NC \type {\alignmentcatcode } \NC \the\alignmentcatcode
+\NC \type {\endoflinecatcode } \NC \the\endoflinecatcode \NC \NR
+\NC \type {\parametercatcode } \NC \the\parametercatcode
+\NC \type {\superscriptcatcode} \NC \the\superscriptcatcode \NC \NR
+\NC \type {\subscriptcatcode } \NC \the\subscriptcatcode
+\NC \type {\ignorecatcode } \NC \the\ignorecatcode \NC \NR
+\NC \type {\spacecatcode } \NC \the\spacecatcode
+\NC \type {\lettercatcode } \NC \the\lettercatcode \NC \NR
+\NC \type {\othercatcode } \NC \the\othercatcode
+\NC \type {\activecatcode } \NC \the\activecatcode \NC \NR
+\NC \type {\commentcatcode } \NC \the\commentcatcode
+\NC \type {\invalidcatcode } \NC \the\invalidcatcode \NC \NR
+\stoptabulate
+
+The first column shows the constant that \CONTEXT\ provides and the
+name indicates the purpose. Here are two examples:
\starttyping
-\tokspre\scratchtoks{less stuff}
-\tokspre\scratchtoksone\scratchtokstwo
+\catcode123=\begingroupcatcode
+\catcode125=\endgroupcatcode
\stoptyping
-This prepends the token list that is provided.
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {catcodetable}}]
+
+The catcode table with the given index will become active.
\stopnewprimitive
-\startnewprimitive[title={\prm {etokspre}}]
+\startnewprimitive[title={\prm {cdef}}]
-A variant of \prm {tokspre} is the following: it expands the to be prepended
-content.
+This primitive is like \prm {edef} but in some usage scenarios is slightly
+more efficient because (delayed) expansion is ignored which in turn saves
+building a temporary token list.
+
+\startbuffer
+\edef\FooA{this is foo} \meaningfull\FooA\crlf
+\cdef\FooB{this is foo} \meaningfull\FooB\par
+\stopbuffer
+
+\typebuffer {\tttf \getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {cdefcsname}}]
+
+This primitive is like \prm {edefcsame} but in some usage scenarios is slightly
+more efficient because (delayed) expansion is ignored which in turn saves
+building a temporary token list.
+
+\startbuffer
+\edefcsname FooA\endcsname{this is foo} \meaningasis\FooA\crlf
+\cdefcsname FooB\endcsname{this is foo} \meaningasis\FooB\par
+\stopbuffer
+
+\typebuffer {\tttf \getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {cfcode}}]
+
+This primitive is a companion to \prm {efcode} and sets the compression factor.
+It takes three values: font, character code, and factor.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {char}}]
+
+This appends a character with the given index in the current font.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {chardef}}]
+
+The following definition relates a control sequence to a specific character:
\starttyping
-\def\temp{less stuff}
-\etokspre\scratchtoks{a bit \temp}
+\chardef\copyrightsign"A9
\stoptyping
+However, because in a context where a number is expected, such a \prm {chardef}
+is seen as valid number, there was a time when this primitive was used to define
+constants without overflowing the by then limited pool of count registers. In
+\ETEX\ aware engines this was less needed, and in \LUAMETATEX\ we have \prm
+{integerdef} as a more natural candidate.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {cleaders}}]
+
+See \prm {gleaders} for an explanation.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {clearmarks}}]
+
+This primitive is an addition to the multiple marks mechanism that originates in
+\ETEX\ and reset the mark registers of the given category (a number).
+
\stopnewprimitive
-\startnewprimitive[title={\prm {gtoksapp}}]
+\startoldprimitive[title={\prm {clubpenalties}}]
-This is the global variant of \prm {toksapp}.
+This is an array of penalty put before the first lines in a paragraph. High values
+discourage (or even prevent) a lone line at the end of a page. This
+command expects a count value indicating the number of entries that will follow.
+The first entry is ends up after the first line.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {clubpenalty}}]
+
+This is the penalty put before a club line in a paragraph. High values discourage
+(or even prevent) a lone line at the end of a next page.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {constant}}]
+
+This prefix tags a macro (without arguments) as being constant. The main
+consequence is that in some cases expansion gets delayed which gives a little
+performance boost and less (temporary) memory usage, for instance in \type
+{\csname} like scenarios.
\stopnewprimitive
-\startnewprimitive[title={\prm {xtoksapp}}]
+\startnewprimitive[title={\prm {constrained}}]
-This is the global variant of \prm {etoksapp}.
+See previous section about \prm {retained}.
\stopnewprimitive
-\startnewprimitive[title={\prm {gtokspre}}]
+\startoldprimitive[title={\prm {copy}}]
-This is the global variant of \prm {tokspre}.
+This is the box register accessor that returns a copy of the box.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {copymathatomrule}}]
+
+This copies the rule bitset from the parent class (second argument) to the target
+class (first argument). The bitset controls the features that apply to atoms.
\stopnewprimitive
-\startnewprimitive[title={\prm {xtokspre}}]
+\startnewprimitive[title={\prm {copymathparent}}]
-This is the global variant of \prm {etokspre}.
+This binds the given class (first argument) to another class (second argument) so
+that one doesn't need to define all properties.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {copymathspacing}}]
+
+This copies an class spacing specification to another one, so in
+
+\starttyping
+\copymathspacing 34 2
+\stoptyping
+
+class 34 (a user one) get the spacing from class 2 (binary).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {count}}]
+
+This accesses a count register by index. This is kind of \quote {not done} unless
+you do it local and make sure that it doesn't influence macros that you call.
+
+\starttyping
+\count4023=10
+\stoptyping
+
+In standard \TEX\ the first 10 counters are special because they get reported to
+the console, and \type {\count0} is then assumed to be the page counter.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {countdef}}]
+
+This primitive relates a control sequence to a count register. Compare this to
+the example in the previous section.
+
+\starttyping
+\countdef\MyCounter4023
+\MyCounter=10
+\stoptyping
+
+However, this is also \quote {not done}. Instead one should use the allocator that
+the macro package provides.
+
+\starttyping
+\newcount\MyCounter
+\MyCounter=10
+\stoptyping
+
+In \LUAMETATEX\ we also have integers that don't rely on registers. These are
+assigned by the primitive \prm {integerdef}:
+
+\starttyping
+\integerdef\MyCounterA 10
+\stoptyping
+
+Or better \type {\newinteger}.
+
+\starttyping
+\newinteger\MyCounterB
+\MyCounterN10
+\stoptyping
+
+There is a lowlevel manual on registers.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {cr}}]
+
+This ends a row in an alignment. It also ends an alignment preamble.
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {crampeddisplaystyle}}]
+
+A less spacy alternative of \prm {displaystyle}; integer representation:
+\the\scriptstyle.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {crampedscriptscriptstyle}}]
+
+A less spacy alternative of \prm {scriptscriptstyle}; integer representation:
+\the\scriptscriptstyle.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {crampedscriptstyle}}]
+
+A less spacy alternative of \prm {scriptstyle}; integer representation:
+\the\scriptstyle.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {crampedtextstyle}}]
+
+A less spacy alternative of \prm {textstyle}; integer representation:
+\the\textstyle.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {crcr}}]
+
+This ends a row in an alignment when it hasn't ended yet.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {csactive}}]
+
+Because \LUATEX\ (and \LUAMETATEX) are \UNICODE\ engines active characters are
+implemented a bit differently. They don't occupy a eight bit range of characters
+but are stored as control sequence with a special prefix \type {U+FFFF} which
+never shows up in documents. The \prm {csstring} primitive injects the name of a
+control sequence without leading escape character, the \prm {csactive} injects
+the internal name of the following (either of not active) character. As we cannot
+display the prefix: \type {\csactive~} will inject the \UTF\ sequences for \type
+{U+FFFF} and \type {U+007E}, so here we get the bytes \type {EFBFBF7E}. Basically
+the next token is preceded by \prm {string}, so when you don't provide a
+character you are in for a surprise.
\stopnewprimitive
@@ -468,6 +2076,819 @@ create a hash entry and defaults its meaning to \prm {relax}.
\stopoldprimitive
+\startnewprimitive[title={\prm {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={\prm {currentgrouplevel}}]
+
+\startbuffer
+[\the\currentgrouplevel] \bgroup
+ [\the\currentgrouplevel] \bgroup
+ [\the\currentgrouplevel]
+ \egroup [\the\currentgrouplevel]
+\egroup [\the\currentgrouplevel]
+\stopbuffer
+
+The next example gives: \inlinebuffer.
+
+\typebuffer
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {currentgrouptype}}]
+
+\startbuffer
+[\the\currentgrouptype] \bgroup
+ [\the\currentgrouptype] \begingroup
+ [\the\currentgrouptype]
+ \endgroup [\the\currentgrouptype]
+ [\the\currentgrouptype] \beginmathgroup
+ [\the\currentgrouptype]
+ \endmathgroup [\the\currentgrouptype]
+[\the\currentgrouptype] \egroup
+\stopbuffer
+
+The next example gives: \inlinebuffer.
+
+\typebuffer
+
+The possible values depend in the engine and for \LUAMETATEX\ they are:
+
+\startluacode
+context.startcolumns { n = 4 }
+context.starttabulate { "|r|l|" }
+for i=0,#tex.groupcodes do
+ context.NC() context(i)
+ context.NC() context(tex.groupcodes[i])
+ context.NC() context.NR()
+end
+context.stoptabulate()
+context.stopcolumns()
+\stopluacode
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {currentifbranch}}]
+
+\startbuffer
+[\the\currentifbranch] \iftrue
+ [\the\currentifbranch] \iffalse
+ [\the\currentifbranch]
+ \else
+ [\the\currentifbranch]
+ \fi [\the\currentifbranch]
+\fi [\the\currentifbranch]
+\stopbuffer
+
+The next example gives: \inlinebuffer.
+
+\typebuffer
+
+So when in the \quote {then} branch we get plus one and when in the \quote {else}
+branch we end up with a minus one.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {currentiflevel}}]
+
+\startbuffer
+[\the\currentiflevel] \iftrue
+ [\the\currentiflevel]\iftrue
+ [\the\currentiflevel] \iftrue
+ [\the\currentiflevel]
+ \fi [\the\currentiflevel]
+ \fi [\the\currentiflevel]
+\fi [\the\currentiflevel]
+\stopbuffer
+
+The next example gives: \inlinebuffer.
+
+\typebuffer
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {currentiftype}}]
+
+\startbuffer
+[\the\currentiftype] \iftrue
+ [\the\currentiftype]\iftrue
+ [\the\currentiftype] \iftrue
+ [\the\currentiftype]
+ \fi [\the\currentiftype]
+ \fi [\the\currentiftype]
+\fi [\the\currentiftype]
+\stopbuffer
+
+The next example gives: \inlinebuffer.
+
+\typebuffer
+
+The values are engine dependent:
+
+\startluacode
+local t = tex.getiftypes()
+context.startcolumns { n = 5 }
+context.starttabulate { "|r|l|" }
+for i=0,#tex.groupcodes do
+ context.NC() context(i)
+ context.NC() context(t[i])
+ context.NC() context.NR()
+end
+context.stoptabulate()
+context.stopcolumns()
+\stopluacode
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {currentloopiterator}}]
+
+Here we show the different expanded loop variants:
+
+\startbuffer
+\edef\testA{\expandedloop 1 10 1{!}}
+\edef\testB{\expandedrepeat 10 {!}}
+\edef\testC{\expandedendless {\ifnum\currentloopiterator>10 \quitloop\else !\fi}}
+\edef\testD{\expandedendless {\ifnum#I>10 \quitloop\else !\fi}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+All these give the same result:
+
+\startlines \tt
+\meaningasis\testA
+\meaningasis\testB
+\meaningasis\testC
+\meaningasis\testD
+\stoplines
+
+The \type {#I} is a shortcut to the current loop iterator; other shortcuts are
+\type {#P} for the parent iterator value and \type {#G} for the grand parent.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {currentloopnesting}}]
+
+This integer reports how many nested loops are currently active. Of course in
+practice the value only has meaning when you know at what outer level your nested
+loop started.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {currentmarks}}]
+
+Marks only get updated when a page is split off or part of a box using \prm
+{vsplit} gets wrapped up. This primitive gives access to the current value of a
+mark and takes the number of a mark class.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {currentstacksize}}]
+
+This is more diagnostic feature than a useful one but we show it anyway. There is
+some basic overhead when we enter a group:
+
+\startbuffer
+\bgroup [\the\currentstacksize]
+ \bgroup [\the\currentstacksize]
+ \bgroup [\the\currentstacksize]
+ [\the\currentstacksize] \egroup
+ [\the\currentstacksize] \egroup
+[\the\currentstacksize] \egroup
+\stopbuffer
+
+\typebuffer \getbuffer
+
+As soon as we define something or change a value, the stack gets populated by
+information needed for recovery after the group ends.
+
+\startbuffer
+\bgroup [\the\currentstacksize]
+ \scratchcounter 1
+ \bgroup [\the\currentstacksize]
+ \scratchdimen 1pt
+ \scratchdimen 2pt
+ \bgroup [\the\currentstacksize]
+ \scratchcounter 2
+ \scratchcounter 3
+ [\the\currentstacksize] \egroup
+ [\the\currentstacksize] \egroup
+[\the\currentstacksize] \egroup
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The stack also keeps some state information, for instance when a box is being
+built. In \LUAMETATEX\ that is is quite a bit more than in other engines but it
+is compensated by more efficient save stack handling elsewhere.
+
+\startbuffer
+\hbox \bgroup [\the\currentstacksize]
+ \hbox \bgroup [\the\currentstacksize]
+ \hbox \bgroup [\the\currentstacksize]
+ [\the\currentstacksize] \egroup
+ [\the\currentstacksize] \egroup
+[\the\currentstacksize] \egroup
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {day}}]
+
+This internal number starts out with the day that the job started.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {dbox}}]
+
+A \prm {dbox} is just a \prm {vbox} (baseline at the bottom) but it has the
+property \quote {dual baseline} which means that is some cases it will behave
+like a \prm {vtop} (baseline at the top) too. Like:
+
+\ruledhbox\bgroup \showstruts
+ \ruleddbox {\hsize 3cm \strut dbox \par \strut dbox \par\strut dbox }
+ \ruledvbox {\hsize 3cm \strut vbox \par \strut vbox \par\strut vbox }
+ \ruledvtop {\hsize 3cm \strut vtop \par \strut vtop \par\strut vtop }
+ \ruledvcenter{\hsize 3cm \strut vcenter \par \strut vcenter \par\strut vcenter}%
+\egroup
+
+A \type {\dbox} behaves like a \type {\vtop} when it's appended to a vertical list which
+means that the height of the first box or rule determines the (base)line correction that
+gets applied.
+
+% This example is taken from lowlevel-boxes:
+
+\startlinecorrection
+\startcombination [nx=3,ny=1,location=top]
+ {\vbox \bgroup \hsize .3\textwidth
+ \small\small \setupalign[tolerant,stretch] \dontcomplain
+ xxxxxxxxxxxxxxxx\par
+ \ruledvbox{\samplefile{ward}}\par
+ xxxxxxxxxxxxxxxx\par
+ \egroup} {\type {\vbox}}
+ {\vbox \bgroup \hsize .3\textwidth
+ \small\small \setupalign[tolerant,stretch] \dontcomplain
+ xxxxxxxxxxxxxxxx\par
+ \ruledvtop{\samplefile{ward}}\par
+ xxxxxxxxxxxxxxxx\par
+ \egroup} {\type {\vtop}}
+ {\vbox \bgroup \hsize .3\textwidth
+ \small\small \setupalign[tolerant,stretch] \dontcomplain
+ xxxxxxxxxxxxxxxx\par
+ \ruleddbox{\samplefile{ward}}\par
+ xxxxxxxxxxxxxxxx\par
+ \egroup} {\type {\dbox}}
+\stopcombination
+\stoplinecorrection
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {deadcycles}}]
+
+This counter is incremented every time the output routine is entered. When \prm
+{maxdeadcycles} is reached \TEX\ will issue an error message, so you'd better
+reset its value when a page is done.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {def}}]
+
+This is the main definition command, as in:
+
+\starttyping
+\def\foo{l me}
+\stoptyping
+
+with companions like \prm {gdef}, \prm {edef}, \prm {xdef}, etc. and variants
+like:
+
+\starttyping
+\def\foo#1{... #1...}
+\stoptyping
+
+where the hash is used in the preamble and for referencing. More about that can
+be found in the low level manual about macros.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {defaulthyphenchar}}][obsolete=yes]
+
+When a font is loaded its hyphen character is set to this value. It can be
+changed afterwards. However, in \LUAMETATEX\ font loading is under \LUA\ control
+so these properties can be set otherwise.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {defaultskewchar}}][obsolete=yes]
+
+When a font is loaded its skew character is set to this value. It can be changed
+afterwards. However, in \LUAMETATEX\ font loading is under \LUA\ control so these
+properties can be set otherwise. Also, \OPENTYPE\ math fonts have top anchor
+instead.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {defcsname}}]
+
+We now get a series of log clutter avoidance primitives. It's fine if you argue
+that they are not really needed, just don't use them.
+
+\starttyping
+\expandafter\def\csname MyMacro:1\endcsname{...}
+ \defcsname MyMacro:1\endcsname{...}
+\stoptyping
+
+The fact that \TEX\ has three (expanded and global) companions can be seen as a
+signal that less verbosity makes sense. It's just that macro packages use plenty
+of \prm {csname}'s.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {deferred}}]
+
+This is mostly a compatibility prefix and it can be checked at the \LUA\ end when
+there is a \LUA\ based assignment going on. It is the counterpart of \prm
+{immediate}. In the traditional engines a \prm {write} is normally deferred
+(turned into a node) and can be handled \prm {immediate}, while a \prm {special}
+does the opposite.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {delcode}}][obsolete=yes]
+
+This assigns delimiter properties to an eight bit character so it has little use
+in an \OPENTYPE\ math setup. WHen the assigned value is hex encoded, the first
+byte denotes the small family, then we have two bytes for the small index,
+followed by three similar bytes for the large variant.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {delimiter}}][obsolete=yes]
+
+This command inserts a delimiter with the given specification. In \OPENTYPE\ math
+we use a different command so it is unlikely that this primitive is used in
+\LUAMETATEX. It takes a number that can best be coded hexadecimal: one byte for
+the class, one for the small family, two for the small index, one for the large
+family and two for the large index. This demonstrates that it can't handle wide
+fonts. Also, in \OPENTYPE\ math fonts the larger sizes and extensible come from
+the same font as the small symbol. On top of that, in \LUAMETATEX\ we have more
+classes than fit in a byte.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {delimiterfactor}}][obsolete=yes]
+
+This is one of the parameters that determines the size of a delimiter: at least
+this factor times the formula height divided by 1000. In \OPENTYPE\ math
+different properties and strategies are used.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {delimitershortfall}}][obsolete=yes]
+
+This is one of the parameters that determines the size of a delimiter: at least
+the formula height minus this parameter. In \OPENTYPE\ math different properties
+and strategies are used.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {detokened}}]
+
+The following token will be serialized into characters with category \quote
+{other}.
+
+\startbuffer
+\toks0{123}
+\def\foo{let's be \relax'd}
+\def\oof#1{let's see #1}
+\detokened\toks0
+\detokened\foo
+\detokened\oof
+\detokened\setbox
+\detokened X
+\stopbuffer
+
+\typebuffer
+
+Gives:
+
+\startlines\tt
+\getbuffer
+\stoplines
+
+Macros with arguments are not shown.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {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
+\expandafter\let\expandafter\temp\detokenize{A} \meaning\temp
+\stopbuffer
+
+\typebuffer
+
+\startlines \tttf \getbuffer \stoplines
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {detokenized}}]
+
+The following (single) token will be serialized into characters with category
+\quote {other}.
+
+\startbuffer
+\toks0{123}
+\def\foo{let's be \relax'd}
+\def\oof#1{let's see #1}
+\detokenized\toks0
+\detokenized\foo
+\detokenized\oof
+\detokenized\setbox
+\detokenized X
+\stopbuffer
+
+\typebuffer
+
+Gives:
+
+\startlines\tt
+\getbuffer
+\stoplines
+
+It is one of these new primitives that complement others like \prm {detokened}
+and such, and they are often mostly useful in experiments of some low level
+magic, which made them stay.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {dimen}}]
+
+Like \prm {count} this is a register accessor which is described in more
+detail in a low level manual.
+
+\starttyping
+\dimen0=10pt
+\stoptyping
+
+While \TEX\ has some assumptions with respect to the first ten count registers
+(as well as the one that holds the output, normally 255), all dimension registers
+are treated equal. However, you need to be aware of clashes with other usage.
+Therefore you can best use the predefined scratch registers or define dedicate
+ones with the \type {\newdimen} macro.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {dimendef}}]
+
+This primitive is used by the \type {\newdimen} macro when it relates a control
+sequence with a specific register. Only use it when you know what you're doing.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {dimensiondef}}]
+
+A variant of \prm {integerdef} is:
+
+\starttyping
+\dimensiondef\MyDimen = 1234pt
+\stoptyping
+
+The properties are comparable to the ones described in the section \prm
+{integerdef}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {dimexpr}}]
+
+This primitive is similar to of \prm {numexpr} but operates on dimensions
+instead. Integer quantities are interpreted as dimensions in scaled points.
+
+\startbuffer
+\the\dimexpr (1pt + 2pt - 5pt) * 10 / 2 \relax
+\stopbuffer
+
+\typebuffer
+
+gives: \inlinebuffer. You can mix in symbolic integers and dimensions. This doesn't work:
+
+\startbuffer
+\the\dimexpr 10 * (1pt + 2pt - 5pt) / 2 \relax
+\stopbuffer
+
+because the engine scans for a dimension and only for an integer (or equivalent)
+after a \type {*} or \type {/}.
+
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {dimexpression}}]
+
+This command is like \prm {numexpression} but results in a dimension instead of
+an integer. Where \prm {dimexpr} doesn't like \typ {2 * 10pt} this expression
+primitive is quite happy with it.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {directlua}}]
+
+This is the low level interface to \LUA:
+
+\startbuffer
+\directlua { tex.print ("Greetings from the lua end!") }
+\stopbuffer
+
+Gives: \quotation {\inlinebuffer} as expected. In \LUA\ we have access to all
+kind of internals of the engine. In \LUAMETATEX\ the interfaces have been
+polished and extended compared to \LUATEX. Although many primitives and
+mechanisms were added to the \TEX\ frontend, the main extension interface remains
+\LUA. More information can be found in documents that come with \CONTEXT, in
+presentations and in articles.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {discretionary}}]
+
+The three snippets given with this command determine the pre, post and replace
+component of the injected discretionary node. The \type {penalty} keyword permits
+setting a penalty with this node. The \type {postword} keyword indicates that
+this discretionary starts a word, and \type {preword} ends it. With \type {break}
+the line break algorithm will prefer a pre or post component over a replace, and
+with \type {nobreak} replace will win over pre. With \type {class} you can set a
+math class that will determine spacing and such for discretionaries used in math
+mode.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {discretionaryoptions}}]
+
+Processing of discretionaries is controlled by this bitset:
+
+\getbuffer[engine:syntax:discoptioncodes]
+
+These can also be set on \prm {discretionary} using the \type {options} key.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {displayindent}}]
+
+The \prm {displaywidth}, \prm {displayindent} and \prm {predisplaysize}
+parameters are set by the line break routine (but can be adapted by the user), so
+that mid|-|par display formula can adapt itself to hanging indentation and par
+shapes. I order to calculate thee values and adapt the line break state
+afterwards such a display formula is assumed to occupy three lines, so basically
+a rather compact formula.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {displaylimits}}]
+
+By default in math display mode limits are place on top while in inline mode they
+are placed like scripts, after the operator. Placement can be forced with the
+\prm {limits} and \prm {nolimits} modifiers (after the operator). Because there
+can be multiple of these in a row there is \prm {displaylimits} that forces the
+default placement, so effectively it acts here as a reset modifier.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {displaystyle}}]
+
+One of the main math styles; integer representation: \the\displaystyle.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {displaywidowpenalties}}]
+
+This is a math specific variant of \prm {widowpenalties}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {displaywidowpenalty}}]
+
+This is a math specific variant of \prm {widowpenalty}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {displaywidth}}]
+
+This parameter determines the width of the formula and normally defaults to the
+\prm {hsize} unless we are in the middle of a paragraph in which case it is
+compensated for hanging indentation or the par shape.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {divide}}]
+
+The \prm {divide} operation can be applied to integers, dimensions, float,
+attribute and glue quantities. There are subtle rounding differences between
+the divisions in expressions and \prm {divide}:
+
+\starttabulate
+\NC \type {\scratchcounter1049 \numexpr\scratchcounter/ 10\relax}
+\EQ \scratchcounter1049 \the\numexpr\scratchcounter/ 10\relax
+\NC \NR
+\NC \type {\scratchcounter1049 \numexpr\scratchcounter: 10\relax}
+\EQ \scratchcounter1049 \the\numexpr\scratchcounter: 10\relax
+\NC \NR
+\NC \type {\scratchcounter1049 \divide\scratchcounter by 10}
+\EQ \scratchcounter1049 \divide\scratchcounter by 10
+ \the\scratchcounter
+\NC \NR
+\stoptabulate
+
+The \type {:} divider in \prm {dimexpr} is something that we introduced in
+\LUATEX.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {divideby}}]
+
+This is slightly more efficient variant of \prm {divide} that doesn't look for
+\type {by}. See previous section.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {doubleadjdemerits}}]
+
+This penalty will be added to the penalty assigned to a breakpoint that results
+in two incompatible lines (in \LUAMETATEX\ we can be more granular with respect
+to compatible lines and this concerns a larger delta).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {doublehyphendemerits}}]
+
+This penalty will be added to the penalty assigned to a breakpoint that results
+in two lines ending with a hyphen.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {dp}}]
+
+Returns the depth of the given box.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {dpack}}]
+
+This does what \prm {dbox} does but without callback overhead.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {dsplit}}]
+
+This is the dual baseline variant of \prm {vsplit} (see \prm {dbox} for what that
+means).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {dump}}]
+
+This finishes an (ini) run and dumps a format (basically the current state of the
+engine).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {edef}}]
+
+This is the expanded version of \prm {def}.
+
+\startbuffer
+\def \foo{foo} \meaning\foo
+\def \ofo{\foo\foo} \meaning\ofo
+\edef\oof{\foo\foo} \meaning\oof
+\stopbuffer
+
+\typebuffer
+
+Because \type {\foo} is unprotected it will expand inside the body definition:
+
+\startlines \tt
+\getbuffer
+\stoplines
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {edefcsname}}]
+
+This is the companion of \prm {edef}:
+
+\starttyping
+\expandafter\edef\csname MyMacro:1\endcsname{...}
+ \edefcsname MyMacro:1\endcsname{...}
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {edivide}}]
+
+When expressions were introduced the decision was made to round the divisions which is
+incompatible with the way \prm {divide} works. The expression scanners in \LUAMETATEX\
+compensates that by providing a \type {:} for integer division. The \prm {edivide} does
+the opposite: it rounds the way expressions do.
+
+\startbuffer
+\the\dimexpr .4999pt : 2 \relax =.24994pt
+\the\dimexpr .4999pt / 2 \relax =.24995pt
+\scratchdimen.4999pt \divide \scratchdimen 2 \the\scratchdimen=.24994pt
+\scratchdimen.4999pt \edivide\scratchdimen 2 \the\scratchdimen=.24995pt
+
+\the\numexpr 1001 : 2 \relax =500
+\the\numexpr 1001 / 2 \relax =501
+\scratchcounter1001 \divide \scratchcounter 2 \the\scratchcounter=500
+\scratchcounter1001 \edivide\scratchcounter 2 \the\scratchcounter=501
+\stopbuffer
+
+\typebuffer
+
+Keep in mind that with dimensions we have a fractional part so we actually
+rounding applies to the fraction. For that reason we also provide \prm {rdivide}.
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {edivideby}}]
+
+This the \type {by}|-|less variant of \prm {edivide}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {efcode}}]
+
+This primitive originates in \PDFTEX\ and can be used to set the expansion factor
+of a glyph (characters). This primitive is obsolete because the values can be set
+in the font specification that gets passed via \LUA\ to \TEX. Keep in mind that
+setting font properties at the \TEX\ end is a global operation and can therefore
+influence related fonts. In \LUAMETATEX\ the \prm {cf} code can be used to
+specify the compression factor independent from the expansion factor. The
+primitive takes three values: font, character code, and factor.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {else}}]
+
+This traditional primitive is part of the condition testing mechanism. When a
+condition matches, \TEX\ will continue till it sees an \prm {else} or \prm
+{or} or \prm {orelse} (to be discussed later). It will then do a fast skipping
+pass till it sees an \prm {fi}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {emergencyextrastretch}}]
+
+This is one of the extended parbuilder parameters. You can you it so temporary
+increase the permitted stretch without knowing or messing with the normal value.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {emergencyleftskip}}]
+
+This is one of the extended parbuilder parameters (playground). It permits going
+ragged left in case of a too bad result.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {emergencyrightskip}}]
+
+This is one of the extended parbuilder parameters (playground). It permits going
+ragged right in case of a too bad result.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {emergencystretch}}]
+
+When set the par builder will run a third pass in order to fit the set criteria.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {end}}]
+
+This ends a \TEX\ run, unless of course this primitive is redefined.
+
+\stopoldprimitive
+
\startoldprimitive[title={\prm {endcsname}}]
This primitive is used in combination with \prm {csname}, \prm {ifcsname} and
@@ -476,134 +2897,392 @@ sequence token.
\stopoldprimitive
-\startnewprimitive[title={\prm {begincsname}}]
+\startoldprimitive[title={\prm {endgroup}}]
-The next code creates a control sequence token from the given serialized tokens:
+This is the companion of the \prm {begingroup} primitive that opens a group. See
+\prm {beginsimplegroup} for more info.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {endinput}}]
+
+The engine can be in different input modes: reading from file, reading from a
+token list, expanding a macro, processing something that comes back from \LUA,
+etc. This primitive quits reading from file:
+
+\startbuffer
+this is seen
+\endinput
+here we're already quit
+\stopbuffer
+
+\typebuffer
+
+There is a catch. This is what the above gives:
+
+\getbuffer
+
+but how about this:
+
+\startbuffer
+this is seen
+before \endinput after
+here we're already quit
+\stopbuffer
+
+\typebuffer
+
+Here we get:
+
+\getbuffer
+
+Because a token list is one line, the following works okay:
\starttyping
-\csname mymacro\endcsname
+\def\quitrun{\ifsomething \endinput \fi}
\stoptyping
-When \type {\mymacro} is not defined a control sequence will be created with the
-meaning \prm {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:
+but in a file you'd have to do this when you quit in a conditional:
\starttyping
-\begincsname mymacro\endcsname
+\ifsomething
+ \expandafter \endinput
+\fi
\stoptyping
-This actually is kind of equivalent to:
+While the one|-|liner works as expected:
\starttyping
-\ifcsname mymacro\endcsname
- \csname mymacro\endcsname
-\fi
+\ifsomething \endinput \fi
\stoptyping
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {endlinechar}}]
+
+This is an internal integer register. When set to positive value the character
+with that code point will be appended to the line. The current value is \the
+\endlinechar. Here is an example:
+
+\startbuffer
+\endlinechar\hyphenasciicode
+line 1
+line 2
+\stopbuffer
+
+\typebuffer
+
+\start \getbuffer \stop
+
+If the character is active, the property is honored and the command kicks in. The
+maximum value is 127 (the maximum character code a single byte \UTF\ character
+can carry.)
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {endlocalcontrol}}]
+
+See \prm {beginlocalcontrol}.
+
\stopnewprimitive
-\startnewprimitive[title={\prm {lastnamedcs}}]
+\startnewprimitive[title={\prm {endmathgroup}}]
-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).
+This primitive is the counterpart of \prm {beginmathgroup}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {endsimplegroup}}]
+
+This one ends a simple group, see \prm {beginsimplegroup} for an explanation
+about grouping primitives.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {enforced}}]
+
+The engine can be set up to prevent overloading of primitives and macros defined
+as \prm {permanent} or \prm {immutable}. However, a macro package might want
+to get around this in controlled situations, which is why we have a \prm
+{enforced} prefix. This prefix in interpreted differently in so called \quote
+{ini} mode when macro definitions can be dumped in the format. Internally they
+get an \type {always} flag as indicator that in these places an overload is
+possible.
\starttyping
-\ifcsname mymacro\endcsname
- \csname mymacro\endcsname
-\fi
+\permanent\def\foo{original}
+
+\def\oof {\def\foo{fails}}
+\def\oof{\enforced\def\foo{succeeds}}
\stoptyping
-Instead we can say:
+Of course this only has an effect when overload protection is enabled.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {eofinput}}]
+
+This is a variant on \prm {input} that takes a token list as first argument. That
+list is expanded when the file ends. It has companion primitives \prm
+{atendoffile} (single token) and \prm {atendoffiled} (multiple tokens).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {eqno}}]
+
+This primitive stores the (typeset) content (presumably a number) and when the
+display formula is wrapped that number will end up right of the formula.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {errhelp}}]
+
+This is additional help information to \prm {errmessage} that triggers an error
+and shows a message.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {errmessage}}]
+
+This primitive expects a token list and shows its expansion on the console
+and|/|or in the log file, depending on how \TEX\ is configured. After that it
+will enter the error state and either goes on or waits for input, again depending
+on how \TEX\ is configured. For the record: we don't use this primitive in
+\CONTEXT.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {errorcontextlines}}]
+
+This parameter determines the number on lines shown when an error is triggered.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {errorstopmode}}]
+
+This directive stops at every opportunity to interact. In \CONTEXT\ we overload
+the actions in a callback and quit the run because we can assume that a
+successful outcome is unlikely.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {escapechar}}]
+
+This internal integer has the code point of the character that get prepended to a
+control sequence when it is serialized (for instance in tracing or messages).
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {etoks}}]
+
+This assigns an expanded token list to a token register:
\starttyping
-\ifcsname mymacro\endcsname
- \lastnamedcs
-\fi
+\def\temp{less stuff}
+\etoks\scratchtoks{a bit \temp}
\stoptyping
-Although there can be some performance benefits another advantage is that it uses
-less tokens and parsing. It might even look nicer.
+The orginal value of the register is lost.
\stopnewprimitive
-\startnewprimitive[title={\prm {futureexpand}}]
+\startnewprimitive[title={\prm {etoksapp}}]
-This primitive can be used as an alternative to a \prm {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.}
+A variant of \prm {toksapp} is the following: it expands the to be appended
+content.
+
+\starttyping
+\def\temp{more stuff}
+\etoksapp\scratchtoks{some \temp}
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {etokspre}}]
+
+A variant of \prm {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={\prm {eufactor}}]
+
+When we introduced the \type {es} (2.5cm) and \type {ts} (2.5mm) units as metric
+variants of the \type {in} we also added the \type {eu} factor. One \type {eu}
+equals one tenth of a \type {es} times the \prm {eufactor}. The \type {ts} is a
+convenient offset in test files, the \type {es} a convenient ones for layouts and
+image dimensions and the \type {eu} permits definitions that scale nicely without
+the need for dimensions. They also were a prelude to what later became possible
+with \prm {associateunit}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {everybeforepar}}]
+
+This token register is expanded before a paragraph is triggered. The reason for
+triggering is available in \prm {lastpartrigger}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {everycr}}]
+
+This token list gets expanded when a row ends in an alignment. Normally it will
+use \prm {noalign} as wrapper
\startbuffer
-\def\variantone<#1>{(#1)}
-\def\varianttwo#1{[#1]}
-\futureexpand<\variantone\varianttwo<one>
-\futureexpand<\variantone\varianttwo{two}
+{\everycr{\noalign{H}} \halign{#\cr test\cr test\cr}}
+{\everycr{\noalign{V}} \hsize 4cm \valign{#\cr test\cr test\cr}}
\stopbuffer
\typebuffer
-So, the next token determines which of the two variants is taken:
+Watch how the \prm {cr} ending the preamble also get this treatment:
-{\getbuffer}
+\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:
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {everydisplay}}]
+
+This token list gets expanded every time we enter display mode. It is a companion
+of \prm {everymath}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {everyeof}}]
+
+The content of this token list is injected when a file ends but it can only be
+used reliably when one is really sure that no other file is loaded in the
+process. So in the end it is of no real use in a more complex macro package.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {everyhbox}}]
+
+This token list behaves similar to \prm {everyvbox} so look there for an
+explanation.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {everyjob}}]
+
+This token list register is injected at the start of a job, or more precisely,
+just before the main control loop starts.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {everymath}}]
+
+Often math needs to be set up independent from the running text and this token
+list can be used to do that. There is also \prm {everydisplay}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {everymathatom}}]
+
+When a math atom is seen this tokenlist is expanded before content is processed
+inside the atom body.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {everypar}}]
+
+When a paragraph starts this tokenlist is expanded before content is processed.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {everytab}}]
+
+This token list gets expanded every time we start a table cell in \prm {halign} or
+\prm {valign}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {everyvbox}}]
+
+This token list gets expanded every time we start a vertical box. Like \prm
+{everyhbox} this is not that useful unless you are certain that there are no
+nested boxes that don't need this treatment. Of course you can wipe this register
+in this expansion, like:
+
+\starttyping
+\everyvbox{\kern10pt\everyvbox{}}
+\stoptyping
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {exceptionpenalty}}]
+
+In exceptions we can indicate a penalty by \type {[digit]} in which case a
+penalty is injected set by this primitive, multiplied by the digit.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {exhyphenchar}}]
+
+The character that is used as pre component of the related discretionary.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {exhyphenpenalty}}]
+
+The penalty injected after \type {-} or \type {\-} unless \prm {hyphenationmode}
+is set to force the dedisated penalties.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {expand}}]
+
+Beware, this is not a prefix but a directive to ignore the protected characters of
+the following macro.
\startbuffer
-\def\variantone<#1>{(#1)}
-\def\varianttwo{}
-\def\temp{\futureexpand<\variantone\varianttwo}
-[\temp <one>]
-[\temp {two}]
-[\expandafter\temp\space <one>]
-[\expandafter\temp\space {two}]
+\protected \def \testa{\the\scratchcounter}
+ \edef\testb{\testa}
+ \edef\testc{\expand\testa}
\stopbuffer
\typebuffer
-This gives us:
+The meaning of the three macros is:
-{\getbuffer}
+\startlines \getbuffer \tttf
+\meaningfull\testa
+\meaningfull\testb
+\meaningfull\testc
+\stoplines
\stopnewprimitive
-\startnewprimitive[title={\prm {futureexpandis}}]
+\startnewprimitive[title={\prm {expandactive}}]
-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.
+This a bit of an outlier and mostly there for completeness.
\startbuffer
-\def\variantone<#1>{(#1)}
-\def\varianttwo{}
-\def\temp{\futureexpandis<\variantone\varianttwo}
-[\temp <one>]
-[\temp {two}]
-[\expandafter\temp\space <one>]
-[\expandafter\temp\space {two}]
+ \meaningasis~
+\edef\foo{~} \meaningasis\foo
+\edef\foo{\expandactive~} \meaningasis\foo
\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 \prm {edef} and no \type {\globalexpandeddef} but \prm
-{xdef}.
-
-{\getbuffer}
+There seems to be no difference but the real meaning of the first \type {\foo} is
+\quote {active character 126} while the second \type {\foo} \quote {protected
+call ~} is.
-\stopnewprimitive
+% \showluatokens\foo
-\startnewprimitive[title={\prm {futureexpandisap}}]
+\startlines
+\getbuffer
+\stoplines
-This primitive is like the one in the previous section but also ignores par
-tokens, so \type {isap} means \quote {ignore spaces and paragraphs}.
+Of course the definition of the active tilde is \CONTEXT\ specific and situation
+dependent.
\stopnewprimitive
@@ -625,6 +3304,27 @@ row then.
\stopoldprimitive
+\startnewprimitive[title={\prm {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 \prm {par} and therefore
+ignored.
+
+\stopnewprimitive
+
\startnewprimitive[title={\prm {expandafterspaces}}]
This is a gobbler: the next token is reinjected after following spaces have been
@@ -646,24 +3346,176 @@ a space (and leading spaces in a line are normally being ingored anyway).
\stopnewprimitive
-\startnewprimitive[title={\prm {expandafterpars}}]
+\startnewprimitive[title={\prm {expandcstoken}}]
-Here is another gobbler: the next token is reinjected after following spaces
-and par tokens have been read. So:
+The rationale behind this primitive is that when we \prm {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 \prm {let}
+into the input.
\startbuffer
-[\expandafterpars 1 2]
-[\expandafterpars 3
-4]
-[\expandafterpars 5
+\let\tempA + \meaning\tempA
-6]
+\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
-gives us: \inlinebuffer, because empty lines are like \prm {par} and therefore
-ignored.
+The meaning of the \prm {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={\prm {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}
+ \def\B#1{\string#1} \normalexpanded{\noexpand\B{\A}}
+\protected\def\B#1{\string#1} \B{\A}
+\stopbuffer
+
+\typebuffer \startlines\getbuffer\stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {expandedafter}}]
+
+The following two lines are equivalent:
+
+\startbuffer
+\def\foo{123}
+\expandafter[\expandafter[\expandafter\secondofthreearguments\foo]]
+\expandedafter{[[\secondofthreearguments}\foo]]
+\stopbuffer
+
+\typebuffer
+
+In \CONTEXT\ \MKIV\ the number of times that one has multiple \prm {expandafter}s
+is much larger than in \CONTEXT\ \LMTX\ thanks to some of the new features in
+\LUAMETATEX, and this primitive is not really used yet in the core code.
+
+\startlines\getbuffer\stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {expandeddetokenize}}]
+
+This is a companion to \prm {detokenize} that expands its argument:
+
+\startbuffer
+\def\foo{12#H3}
+\def\oof{\foo}
+\detokenize {\foo} \detokenize {\oof}
+\expandeddetokenize{\foo} \expandeddetokenize{\oof}
+\edef\ofo{\expandeddetokenize{\foo}} \meaningless\ofo
+\edef\ofo{\expandeddetokenize{\oof}} \meaningless\ofo
+\stopbuffer
+
+\typebuffer
+
+This is a bit more convenient than
+
+\starttyping
+\detokenize \expandafter {\normalexpanded {\foo}}
+\stoptyping
+
+kind of solutions. We get:
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {expandedendless}}]
+
+This one loops forever but because the loop counter is not set you need to find a
+way to quit it.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {expandedloop}}]
+
+This variant of the previously introduced \prm {localcontrolledloop} doesn't
+enter a local branch but immediately does its work. This means that it can be
+used inside an expansion context like \prm {edef}.
+
+\startbuffer
+\edef\whatever
+ {\expandedloop 1 10 1
+ {\scratchcounter=\the\currentloopiterator\relax}}
+
+\meaningasis\whatever
+\stopbuffer
+
+\typebuffer
+
+\start \veryraggedright \tt\tfx \getbuffer \stop \blank
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {expandedrepeat}}]
+
+This one takes one instead of three arguments which is sometimes more
+convenient.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {expandparameter}}]
+
+This primitive is a predecessor of \prm {parameterdef} so we stick to a simple
+example.
+
+\startbuffer
+\def\foo#1#2%
+ {\integerdef\MyIndexOne\parameterindex\plusone % 1
+ \integerdef\MyIndexTwo\parameterindex\plustwo % 2
+ \oof{P}\oof{Q}\oof{R}\norelax}
+
+\def\oof#1%
+ {<1:\expandparameter\MyIndexOne><1:\expandparameter\MyIndexOne>%
+ #1%
+ <2:\expandparameter\MyIndexTwo><2:\expandparameter\MyIndexTwo>}
+
+\foo{A}{B}
+\stopbuffer
+
+\typebuffer
+
+In principle the whole parameter stack can be accessed but often
+one never knows if a specific macro is called nested. The original
+idea behind this primitive was tracing but it can also be used to
+avoid passing parameters along a chain of calls.
+
+\getbuffer
\stopnewprimitive
@@ -692,17 +3544,17 @@ catcode|/|character combinations as signals and there is no reason to change
those internals. That said:
\startbuffer
-\edef\tempA{\expandtoken 9 `X} \meaning\tempA
-\edef\tempB{\expandtoken 10 `X} \meaning\tempB
-\edef\tempC{\expandtoken 11 `X} \meaning\tempC
-\edef\tempD{\expandtoken 12 `X} \meaning\tempD
+\xdef\tempA{\expandtoken 9 `X} \meaning\tempA
+\xdef\tempB{\expandtoken 10 `X} \meaning\tempB
+\xdef\tempC{\expandtoken 11 `X} \meaning\tempC
+\xdef\tempD{\expandtoken 12 `X} \meaning\tempD
\stopbuffer
\typebuffer
are all valid and from the meaning you cannot really deduce what's in there:
-\startlines \tttf \getbuffer \stoplines
+\startlines \tttf \getbuffer \stoplines % grouped therefore xdef
But you can be assured that:
@@ -722,817 +3574,1419 @@ characters with catcode 10 are spaces, while those with code 9 are ignored.
\stopnewprimitive
-\startnewprimitive[title={\prm {expandcstoken}}]
+\startnewprimitive[title={\prm {expandtoks}}]
-The rationale behind this primitive is that when we \prm {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 \prm {let}
-into the input.
+This is a more efficient equivalent of \prm {the} applied to a token register,
+so:
\startbuffer
-\let\tempA + \meaning\tempA
+\scratchtoks{just some tokens}
+\edef\TestA{[\the \scratchtoks]}
+\edef\TestB{[\expandtoks\scratchtoks]}
+[\the \scratchtoks] [\TestA] \meaning\TestA
+[\expandtoks\scratchtoks] [\TestB] \meaning\TestB
+\stopbuffer
-\let\tempB X \meaning\tempB \crlf
-\let\tempC $ \meaning\tempC \par
+\typebuffer
-\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
+does the expected:
-\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
+\startlines
+\getbuffer
+\stoplines
-\doifelse{\expandcstoken\tempA}{+}{Y}{N}
-\doifelse{\expandcstoken\tempB}{X}{Y}{N}
-\doifelse{\expandcstoken\tempC}{$}{Y}{N} \par
-\stopbuffer
+The \prm {expandtoken} primitive avoid a copy into the input when there is no
+need for it.
-\typebuffer
+\stopnewprimitive
-The meaning of the \prm {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.
+\startnewprimitive[title={\prm {explicitdiscretionary}}]
-\start \tttf \getbuffer \stop
+This is the verbose alias for one of \TEX's single character control sequences:
+\type {\-}.
-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={\prm {explicithyphenpenalty}}]
+
+The penalty injected after an automatic discretionary \type {\-}, when \prm
+{hyphenationmode} enables this.
\stopnewprimitive
-\startnewprimitive[title={\prm {expand}}]
+\startnewprimitive[title={\prm {explicititaliccorrection}}]
-Normally a protected macro will not be expanded inside for instance an \prm
-{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.}
+This is the verbose alias for one of \TEX's single character control sequences:
+\type {\/}. Italic correction is a character property specific to \TEX\ and the
+concept is not present in modern font technologies. There is a callback that
+hooks into this command so that a macro package can provide its own solution
+to this (or alternatively it can assign values to the italic correction field.
-\startbuffer
-\edef\temp {\doifelse{a}{b}{c}{d}} \meaning\temp \crlf
-\edef\temp{\expand\doifelse{a}{b}{c}{d}} \meaning\temp \par
-\stopbuffer
+\stopnewprimitive
-\typebuffer
+\startnewprimitive[title={\prm {explicitspace}}]
-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.
+This is the verbose alias for one of \TEX's single character control sequences:
+\type {\ }. A space is inserted with properties according the space related
+variables. There is look|-|back involved in order to deal with space factors.
-{\getbuffer}
+When \prm {nospaces} is set to~1 no spaces are inserted, when its value is~2 a
+zero space is inserted.
\stopnewprimitive
-\startoldprimitive[title={\prm {ignorespaces}}]
+\startoldprimitive[title={\prm {fam}}]
-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.
+In a numeric context it returns the current family number, otherwise it sets the
+given family. The number of families in a traditional engine is 16, in \LUATEX\
+it is 256 and in \LUAMETATEX\ we have at most \cldcontext {tex . magicconstants .
+max_n_of_math_families} families. A future version can lower that number when we
+need more classes.
\stopoldprimitive
-\startnewprimitive[title={\prm {ignorepars}}]
+\startoldprimitive[title={\prm {fi}}]
-This is a variant of \prm {ignorespaces}: following spaces {\em and} \type
-{\par} equivalent tokens are ignored, so for instance:
+This traditional primitive is part of the condition testing mechanism and ends a
+test. So, we have:
-\startbuffer
-one + \ignorepars
+\starttyping
+\ifsomething ... \else ... \fi
+\ifsomething ... \or ... \or ... \else ... \fi
+\ifsomething ... \orelse \ifsometing ... \else ... \fi
+\ifsomething ... \or ... \orelse \ifsometing ... \else ... \fi
+\stoptyping
-two = \ignorepars \par
-three
-\stopbuffer
+The \prm {orelse} is new in \LUAMETATEX\ and a continuation like we find in
+other programming languages (see later section).
-\typebuffer
+\stopoldprimitive
-renders as: \inlinebuffer. Traditionally \TEX\ has been sensitive to \prm {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 \prm {par} tokens (and
-\CONTEXT\ set them such that this is the case).
+\startoldprimitive[title={\prm {finalhyphendemerits}}]
+
+This penalty will be added to the penalty assigned to a breakpoint when that
+break results in a pre|-|last line ending with a hyphen.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {firstmark}}][obsolete=yes]
+
+This is a reference to the first mark on the (split off) page, it gives back
+tokens.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {firstmarks}}]
+
+This is a reference to the first mark with the given id (a number) on the (split
+off) page, it gives back tokens.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {firstvalidlanguage}}]
+
+Language id's start at zero, which makes it the first valid language. You can set
+this parameter to indicate the first language id that is actually a language. The
+current value is \the \firstvalidlanguage, so lower values will not trigger
+hyphenation.
\stopnewprimitive
-\startnewprimitive[title={\prm {ignorearguments}}]
+\startnewprimitive[title={\prm {float}}]
-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:
+In addition to integers and dimensions, which are fixed 16.16 integer floats we
+also have \quote {native} floats, based on 32 bit posit unums.
\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 \par
+\float0 = 123.456 \the\float0
+\float2 = 123.456 \the\float0
+\advance \float0 by 123.456 \the\float0
+\advance \float0 by \float2 \the\float0
+\divideby\float0 3 \the\float0
\stopbuffer
\typebuffer
-{\getbuffer}
+They come with the same kind of support as the other numeric data types:
-{\em Todo: explain optional delimiters.}
+\startlines \getbuffer \stoplines
-\stopnewprimitive
+\startbuffer
+\dimen00 = 123.456pt \the\dimen0
+\dimen02 = 123.456pt \the\dimen0
+\advance \dimen0 by 123.456pt \the\dimen0
+\advance \dimen0 by \dimen2 \the\dimen0
+\divideby\dimen0 3 \the\dimen0
+\stopbuffer
-\startnewprimitive[title={\prm {lastarguments}}]
+We leave the subtle differences between floats and dimensions to the user to
+investigate:
-\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} \par
+\typebuffer
-\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} \par
+The nature of posits is that they are more accurate around zero (or smaller
+numbers in general).
+
+\startlines \getbuffer \stoplines
+
+This also works:
+
+\startbuffer
+\float0=123.456e4
+\float2=123.456 \multiply\float2 by 10000
+\the\float0
+\the\float2
\stopbuffer
\typebuffer
-The value of \prm {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
-\prm {everypar} is expanded which in turn can involve macros. You can see that
-in the second block (that is: unless we changed \prm {everypar} in the
-meantime).
+The values are (as expected) the same:
-{\getbuffer}
+\startlines \getbuffer \stoplines
\stopnewprimitive
-\startoldprimitive[title={\prm {scantokens}}]
+\startnewprimitive[title={\prm {floatdef}}]
-Just forget about this \ETEX\ primnitive, just take the one in the next section.
+This primitive defines a symbolic (macro) alias to a float register, just like
+\prm {countdef} and friends do.
-\stopoldprimitive
+\stopnewprimitive
-\startnewprimitive[title={\prm {scantextokens}}]
+\startnewprimitive[title={\prm {floatexpr}}]
-This primitive scans the input as if it comes from a file. In the next examples
-the \prm {detokenize} primitive turns tokenized code into verbatim code that is
-similar to what is read from a file.
+This is the companion of \prm {numexpr}, \prm {dimexpr} etc.
\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}\par
+\scratchcounter 200
+\the \floatexpr 123.456/456.123 \relax
+\the \floatexpr 1.2*\scratchcounter \relax
+\the \floatexpr \scratchcounter/3 \relax
+\number\floatexpr \scratchcounter/3 \relax
\stopbuffer
\typebuffer
-This primitive does not have the end|-|of|-|file side effects of its precursor
-\prm {scantokens}.
+Watch the difference between \prm {the} and \prm {number}:
-{\getbuffer}
+\startlines \getbuffer \stoplines
\stopnewprimitive
-\startoldprimitive[title={\prm {number}}]
+\startoldprimitive[title={\prm {floatingpenalty}}]
-This \TEX\ primitive serializes the next token into a number, assuming that it
-is indeed a number, like
+When an insertion is split (across pages) this one is added to to accumulated
+\prm {insertpenalties}. In \LUAMETATEX\ this penalty can be stored per insertion
+class.
-\starttyping
-\number`A
-\number65
-\number\scratchcounter
-\stoptyping
+\stopoldprimitive
-For counters and such the \prm {the} primitive does the same, but when you're
-not sure if what follows is a verbose number or (for instance) a counter the
-\prm {number} primitive is a safer bet, because \type {\the 65} will not work.
+\startnewprimitive[title={\prm {flushmarks}}]
+
+This primitive is an addition to the multiple marks mechanism that originates in
+\ETEX\ and inserts a reset signal for the mark given category that will perform a
+clear operation (like \prm {clearmarks} which operates immediately).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {font}}]
+
+This primitive is either a symbolic reference to the current font or in the
+perspective of an assignment is used to trigger a font definitions with a given
+name (\type {cs}) and specification. In \LUAMETATEX\ the assignment will trigger
+a callback that then handles the definition; in addition to the filename an
+optional size specifier is checked (\type {at} or \type {scaled}).
+
+In \LUAMETATEX\ {\em all} font loading is delegated to \LUA, and there is no
+loading code built in the engine. Also, instead of \prm {font} in \CONTEXT\ one
+uses dedicated and more advanced font definition commands.
\stopoldprimitive
-\startnewprimitive[title={\prm {tointeger}}]
+\startnewprimitive[title={\prm {fontcharba}}]
+
+Fetches the bottom anchor of a character in the given font, so:
\startbuffer
-\scratchcounter = 1234 \tointeger\scratchcounter
+\the\fontcharba\textfont0 "222B
\stopbuffer
-The following code gives this: {\nospacing\inlinebuffer} and is equivalent to
-\prm {number}.
-
-\typebuffer
+results in: \inlinebuffer. However, this anchor is only available when it is set
+and it is not part of \OPENTYPE; it is something that \CONTEXT\ provides for math
+fonts.
\stopnewprimitive
-\startnewprimitive[title={\prm {tohexadecimal}}]
+\startoldprimitive[title={\prm {fontchardp}}]
+
+Fetches the depth of a character in the given font, so:
\startbuffer
-\scratchcounter = 1234 \tohexadecimal\scratchcounter
+\the\fontchardp\font`g
\stopbuffer
-The following code gives this: {\nospacing\inlinebuffer} with uppercase letters.
+results in: \inlinebuffer.
-\typebuffer
+\stopoldprimitive
-\stopnewprimitive
+\startoldprimitive[title={\prm {fontcharht}}]
-\startnewprimitive[title={\prm {todimension}}]
+Fetches the width of a character in the given font, so:
\startbuffer
-\scratchdimen = 1234pt \todimension\scratchdimen
+\the\fontcharht\font`g
\stopbuffer
-The following code gives this: {\nospacing\inlinebuffer} and like its numeric
-counterparts accepts anything that resembles a number this one goes beyond
-(user, internal or pseudo) registers values too.
+results in: \inlinebuffer.
-\typebuffer
+\stopoldprimitive
-\stopnewprimitive
+\startoldprimitive[title={\prm {fontcharic}}]
-\startnewprimitive[title={\prm {toscaled}}]
+Fetches the italic correction of a character in the given font, but because it is
+not an \OPENTYPE\ property it is unlikely to return something useful. Although
+math fonts have such a property in \CONTEXT\ we deal with it differently.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {fontcharta}}]
+
+Fetches the top anchor of a character in the given font, so:
\startbuffer
-\scratchdimen = 1234pt \toscaled\scratchdimen
+\the\fontcharba\textfont0 "222B
\stopbuffer
-The following code gives this: {\nospacing\inlinebuffer} is similar to \prm
-{todimension} but omits the \type {pt} so that we don't need to revert to some
-nasty stripping code.
-
-\typebuffer
+results in: \inlinebuffer. This is a specific property of math characters because
+in text mark anchoring is driven by a feature.
\stopnewprimitive
-\startnewprimitive[title={\prm {tosparsedimension}}]
+\startoldprimitive[title={\prm {fontcharwd}}]
+
+Fetches the width of a character in the given font, so:
\startbuffer
-\scratchdimen = 1234pt \tosparsedimension\scratchdimen
+\the\fontcharwd\font`g
\stopbuffer
-The following code gives this: {\nospacing\inlinebuffer} where \quote {sparse}
-indicates that redundant trailing zeros are not shown.
+results in: \inlinebuffer.
-\typebuffer
+\stopoldprimitive
-\stopnewprimitive
+\startoldprimitive[title={\prm {fontdimen}}][obsolete=yes]
+
+A traditional \TEX\ font has a couple of font specific dimensions, we only
+mention the seven that come with text fonts:
+
+\startitemize[n,packed]
+\startitem
+ The slant (slope) is an indication that we have an italic shape. The value
+ divided by 65.536 is a fraction that can be compared with for instance the
+ \type {slanted} operator in \METAPOST. It is used for positioning accents, so
+ actually not limited to oblique fonts (just like italic correction can be a
+ property of any character). It is not relevant in the perspective of
+ \OPENTYPE\ fonts where we have glyph specific top and bottom anchors.
+\stopitem
+\startitem
+ Unless is it overloaded by \prm {spaceskip} this determines the space between
+ words (or actually anything separated by a space).
+\stopitem
+\startitem
+ This is the stretch component of \prm {fontdimen}~2(space).
+\startitem
+ This is the shrink component of \prm {fontdimen}~2(space).
+\stopitem
+\startitem
+ The so called ex|-|height is normally the height of the \quote {x} and is
+ also accessible as \type {em} unit.
+\stopitem
+\startitem
+ The so called em|-|width or in \TEX\ speak quad width is about the with of an
+ \quote {M} but in many fonts just matches the font size. It is also
+ accessible as \type {em} unit.
+\stopitem
+\startitem
+ This is a very \TEX\ specific property also known as extra space. It gets
+ {\em added} to the regular space after punctuation when \prm {spacefactor} is
+ 2000 or more. It can be overloaded by \prm {xspaceskip}.
+\stopitem
+\stopitemize
+
+This primitive expects a a number and a font identifier. Setting a font dimension
+is a global operation as it directly pushes the value in the font resource.
-\startnewprimitive[title={\prm {tosparsescaled}}]
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {fontid}}]
+
+Returns the (internal) number associated with the given font:
\startbuffer
-\scratchdimen = 1234pt \tosparsescaled\scratchdimen
+{\bf \xdef\MyFontA{\the\fontid\font}}
+{\sl \xdef\MyFontB{\setfontid\the\fontid\font}}
\stopbuffer
-The following code gives this: {\nospacing\inlinebuffer} where \quote {sparse}
-means that redundant trailing zeros are omitted.
+\typebuffer \getbuffer
+
+with:
+
+\startbuffer
+test {\setfontid\MyFontA test} test {\MyFontB test} test
+\stopbuffer
\typebuffer
+gives: \inlinebuffer.
+
\stopnewprimitive
-\startoldprimitive[title={\prm {numericscale}}]
+\startnewprimitive[title={\prm {fontmathcontrol}}]
+
+The \prm {mathfontcontrol} parameter controls how the engine deals with specific
+font related properties and possibilities. It is set at the \TEX\ end. It makes
+it possible to fine tune behavior in this mixed traditional and not perfect
+\OPENTYPE\ math font arena. One can also set this bitset when initializing
+(loading) the font (at the \LUA\ end) and the value set there is available in
+\prm {fontmathcontrol}. The bits set in the font win over those in \prm
+{mathfontcontrol}. There are a few cases where we set these options in the (so
+called) goodie files. For instance we ignore font kerns in Libertinus, Antykwa
+and some more.
+
+\starttabulate[|l|rT|]
+\NC modern \NC \bgroup\switchtobodyfont [modern]\normalexpanded{\egroup 0x\tohexadecimal\fontmathcontrol\textfont\fam} \NC \NR
+\NC pagella \NC \bgroup\switchtobodyfont [pagella]\normalexpanded{\egroup 0x\tohexadecimal\fontmathcontrol\textfont\fam} \NC \NR
+\NC antykwa \NC \bgroup\switchtobodyfont [antykwa]\normalexpanded{\egroup 0x\tohexadecimal\fontmathcontrol\textfont\fam} \NC \NR
+\NC libertinus \NC \bgroup\switchtobodyfont[libertinus]\normalexpanded{\egroup 0x\tohexadecimal\fontmathcontrol\textfont\fam} \NC \NR
+\stoptabulate
-This primitive can best be explained by a few examples:
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {fontname}}]
+
+Depending on how the font subsystem is implemented this gives some information
+about the used font:
\startbuffer
-\the\numericscale 1323
-\the\numericscale 1323.0
-\the\numericscale 1.323
-\the\numericscale 13.23
+{\tf \fontname\font}
+{\bf \fontname\font}
+{\sl \fontname\font}
\stopbuffer
\typebuffer
-In several places \TEX\ uses a scale but due to the lack of floats it then uses
-1000 as 1.0 replacement. This primitive can be used for \quote {real} scales and
-the period signals this:
+\startlines
+\getbuffer
+\stoplines
-\startlines \getbuffer \stoplines
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {fontspecdef}}]
+
+This primitive creates a reference to a specification that when triggered will
+change multiple parameters in one go.
+
+\starttyping
+\fontspecdef\MyFontSpec
+ \fontid\font
+ scale 1200
+ xscale 1100
+ yscale 800
+ weight 200
+ slant 500
+\relax
+\stoptyping
-When there is a period (indicating the fraction) the result is an integer (count)
-that has the multiplier 1000 applied.
+is equivalent to:
+
+\starttyping
+\fontspecdef\MyFontSpec
+ \fontid\font
+ all 1200 1100 800 200 500
+\relax
+\stoptyping
+
+while
+
+\starttyping
+\fontspecdef\MyFontSpec
+ \fontid\font
+ all \glyphscale \glyphxscale \glyphyscale \glyphslant \glyphweight
+\relax
+\stoptyping
+
+is the same as
+
+\starttyping
+\fontspecdef\MyFontSpec
+ \fontid\font
+\relax
+\stoptyping
+
+The engine adapts itself to these glyph parameters but when you access certain
+quantities you have to make sure that you use the scaled ones. The same is true
+at the \LUA\ end. This is somewhat fundamental in the sense that when one uses
+these sort of dynamic features one also need to keep an eye on code that uses
+font specific dimensions.
\stopnewprimitive
-\startoldprimitive[title={\prm {string}}]
+\startnewprimitive[title={\prm {fontspecid}}]
-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.
+Internally a font reference is a number and this primitive returns the number of
+the font bound to the specification.
-\stopoldprimitive
+\stopnewprimitive
-\startnewprimitive[title={\prm {csstring}}]
+\startnewprimitive[title={\prm {fontspecifiedname}}]
-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.
+Depending on how the font subsystem is implemented this gives some information
+about the (original) definition of the used font:
\startbuffer
-\csstring\mymacro
+{\tf \fontspecifiedname\font}
+{\bf \fontspecifiedname\font}
+{\sl \fontspecifiedname\font}
\stopbuffer
\typebuffer
-We get the name, not the meaning: {\tt \inlinebuffer}.
+\startlines
+\getbuffer
+\stoplines
\stopnewprimitive
-\startoldprimitive[title={\prm {unexpanded}}]
+\startnewprimitive[title={\prm {fontspecifiedsize}}]
-This is an \ETEX\ enhancement. The content will not be expanded in a context
-where expansion is happening, like in an \prm {edef}. In \CONTEXT\ you need to
-use \type {\normalunexpanded} because we already had a macro with that name.
+Depending on how the font subsystem is implemented this gives some information
+about the (original) size of the used font:
\startbuffer
-\def \A{!} \meaning\A
-\def \B{?} \meaning\B
-\edef\C{\A\B} \meaning\C
-\edef\C{\normalunexpanded{\A}\B} \meaning\C
+{\tf \the\fontspecifiedsize\font : \the\glyphscale}
+{\bfa \the\fontspecifiedsize\font : \the\glyphscale}
+{\slx \the\fontspecifiedsize\font : \the\glyphscale}
\stopbuffer
\typebuffer
-\startlines \tttf \getbuffer \stoplines
+Depending on how the font system is setup, this is not the real value that is
+used in the text because we can use for instance \prm {glyphscale}. So the next
+lines depend on what font mode this document is typeset.
-\stopoldprimitive
+\startlines
+\getbuffer
+\stoplines
-\startoldprimitive[title={\prm {detokenize}}]
+\stopnewprimitive
-This \ETEX\ primitive turns the content of the provides list will become
-characters, kind of verbatim.
+\startnewprimitive[title={\prm {fontspecscale}}]
-\startbuffer
-\expandafter\let\expandafter\temp\detokenize{1} \meaning\temp
-\expandafter\let\expandafter\temp\detokenize{A} \meaning\temp
-\stopbuffer
+This returns the scale factor of a fontspec where as usual 1000 means scaling
+by~1.
-\typebuffer
+\stopnewprimitive
-\startlines \tttf \getbuffer \stoplines
+\startnewprimitive[title={\prm {fontspecslant}}]
-\stopoldprimitive
+This returns the slant factor of a font specification, usually between zero and
+1000 with 1000 being maximum slant.
-\startnewprimitive[title={\prm {tokenized}}]
+\stopnewprimitive
-Just as \prm {expanded} has a counterpart \prm {unexpanded}, it makes sense to give
-\prm {detokenize} a companion:
+\startnewprimitive[title={\prm {fontspecweight}}]
-\startbuffer
-\edef\foo{\detokenize{\inframed{foo}}}
-\edef\oof{\detokenize{\inframed{oof}}}
+This returns the weight of the font specification. Reasonable values are between
+zero and 500.
-\meaning\foo \crlf \dontleavehmode\foo
+\stopnewprimitive
-\edef\foo{\tokenized{\foo\foo}}
+\startnewprimitive[title={\prm {fontspecxscale}}]
-\meaning\foo \crlf \dontleavehmode\foo
+This returns the scale factor of a font specification where as usual 1000 means
+scaling by~1.
-\dontleavehmode\tokenized{\foo\oof}
-\stopbuffer
+\stopnewprimitive
-\typebuffer {\tttf \getbuffer}
+\startnewprimitive[title={\prm {fontspecyscale}}]
-This primitive is similar to:
+This returns the scale factor of a font specification where as usual 1000 means
+scaling by~1.
-\starttyping
-\def\tokenized#1{\scantextokens\expandafter{\normalexpanded{#1}}}
-\stoptyping
+\stopnewprimitive
-and should be more efficient, not that it matters much as we don't use it that
-much (if at all).
+\startnewprimitive[title={\prm {fonttextcontrol}}]
+
+This returns the text control flags that are set on the given font, here {\tttf
+0x\tohexadecimal \fonttextcontrol \font}. Bits that can be set are:
+
+\getbuffer[engine:syntax:textcontrolcodes]
\stopnewprimitive
-\startnewprimitive[title={\prm {expanded}}]
+\startnewprimitive[title={\prm {forcedleftcorrection}}]
-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:
+This is a callback driven left correction signal similar to italic corrections.
-\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} \par
-\stopbuffer
+\stopnewprimitive
-\typebuffer {\getbuffer}
+\startnewprimitive[title={\prm {forcedrightcorrection}}]
+
+This is a callback driven right correction signal similar to italic corrections.
\stopnewprimitive
-\startnewprimitive[title={\prm {numexpression}}]
+\startnewprimitive[title={\prm {formatname}}]
-The normal \prm {numexpr} primitive understands the \type {+}, \type {-}, \type
-{*} and \type {/} operators but in \LUAMETATEX\ we also can use \type {:} for a
-non rounded integer division (think of \LUA's \type {//}). if you want more than
-that, you can use the new expression primitive where you can use the following
-operators.
+It is in the name: {\tttf \filenameonly {\formatname}}, but we cheat here by only
+showing the filename and not the full path, which in a \CONTEXT\ setup can span
+more than a line in this paragraph.
-\starttabulate[||cT|cT|]
-\BC add \NC + \NC \NC \NR
-\BC subtract \NC - \NC \NC \NR
-\BC multiply \NC * \NC \NC \NR
-\BC divide \NC / : \NC \NC \NR
-\BC mod \NC \letterpercent \NC mod \NC \NR
-\BC band \NC & \NC band \NC \NR
-\BC bxor \NC ^ \NC bxor \NC \NR
-\BC bor \NC \letterbar \space v \NC bor \NC \NR
-\BC and \NC && \NC and \NC \NR
-\BC or \NC \letterbar\letterbar \NC or \NC \NR
-\BC setbit \NC <undecided> \NC bset \NC \NR
-\BC resetbit \NC <undecided> \NC breset \NC \NR
-\BC left \NC << \NC \NC \NR
-\BC right \NC >> \NC \NC \NR
-\BC less \NC < \NC \NC \NR
-\BC lessequal \NC <= \NC \NC \NR
-\BC equal \NC = == \NC \NC \NR
-\BC moreequal \NC >= \NC \NC \NR
-\BC more \NC > \NC \NC \NR
-\BC unequal \NC <> != \lettertilde = \NC \NC \NR
-\BC not \NC ! \lettertilde \NC not \NC \NR
-\stoptabulate
+\stopnewprimitive
-An example of the verbose bitwise operators is:
+\startnewprimitive[title={\prm {frozen}}]
+
+You can define a macro as being frozen:
\starttyping
-\scratchcounter = \numexpression
- "00000 bor "00001 bor "00020 bor "00400 bor "08000 bor "F0000
-\relax
+\frozen\def\MyMacro{...}
\stoptyping
-In the table you might have notices that some operators have equivalents. This
-makes the scanner a bit less sensitive for catcode regimes.
-
-When \prm {tracingexpressions} is set to one or higher the intermediate \quote
-{reverse polish notation} stack that is used for the calculation is shown, for
-instance:
+When you redefine this macro you get an error:
\starttyping
-4:8: {numexpression rpn: 2 5 > 4 5 > and}
+! You can't redefine a frozen macro.
\stoptyping
-When you want the output on your console, you need to say:
+This is a prefix like \prm {global} and it can be combined with other prefixes.
+\footnote {The \prm {outer} and \prm {long} prefixes are no|-|ops in
+\LUAMETATEX\ and \LUATEX\ can be configured to ignore them.}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {futurecsname}}]
+
+In order to make the repertoire of \type {def}, \type {let} and \type {futurelet}
+primitives complete we also have:
\starttyping
-\tracingexpressions 1
-\tracingonline 1
+\futurecsname MyMacro:1\endcsname\MyAction
\stoptyping
\stopnewprimitive
-\startnewprimitive[title={\prm {dimexpression}}]
+\startnewprimitive[title={\prm {futuredef}}]
-This command is like \prm {numexpression} but results in a dimension instead of
-an integer. Where \prm {dimexpr} doesn't like \typ {2 * 10pt} this expression
-primitive is quite happy with it.
+We elaborate on the example of using \prm {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)\par
+\stopbuffer
+
+\typebuffer
+
+This time we get:
+
+{\getbuffer}
+
+It is for that reason that we now also have \prm {futuredef}:
+
+\startbuffer
+\def\MySpecialToken{[}
+\def\DoWhatever{\ifx\NextToken\MySpecialToken YES\else NOP\fi : }
+\futuredef\NextToken\DoWhatever [A]\crlf
+\futuredef\NextToken\DoWhatever (A)\par
+\stopbuffer
+
+\typebuffer
+
+So we're back to what we want:
+
+{\getbuffer}
\stopnewprimitive
-\startoldprimitive[title={\prm {if}}]
+\startnewprimitive[title={\prm {futureexpand}}]
-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.
+This primitive can be used as an alternative to a \prm {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\A{A}\def\B{B} \chardef\C=`C \chardef\D=`D \def\AA{AA}
+\def\variantone<#1>{(#1)}
+\def\varianttwo#1{[#1]}
+\futureexpand<\variantone\varianttwo<one>
+\futureexpand<\variantone\varianttwo{two}
+\stopbuffer
-[\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]
+\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
-The last example demonstrates that the tokens get expanded, which is why
-we get the extra \type {A}:
+This gives us:
{\getbuffer}
-\stopoldprimitive
+\stopnewprimitive
-\startoldprimitive[title={\prm {ifcat}}]
+\startnewprimitive[title={\prm {futureexpandis}}]
-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).
+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\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]
+\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
-Close reading is needed here:
+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 \prm {edef} and no \type {\globalexpandeddef} but \prm
+{xdef}.
{\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.
+\stopnewprimitive
-\stopoldprimitive
+\startnewprimitive[title={\prm {futureexpandisap}}]
-\startoldprimitive[title={\prm {ifnum}}]
+This primitive is like the one in the previous section but also ignores par
+tokens, so \type {isap} means \quote {ignore spaces and paragraphs}.
-This is a frequently used conditional: it compares two numbers where a number is
-anything that can be seen as such.
+\stopnewprimitive
-\startbuffer
-\scratchcounter=65 \chardef\A=65
+\startoldprimitive[title={\prm {futurelet}}]
-\ifnum65=`A YES \else NOP\fi
-\ifnum\scratchcounter=65 YES \else NOP\fi
-\ifnum\scratchcounter=\A YES \else NOP\fi
+The original \TEX\ primitive \prm {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\MySpecialTokenL[
+\let\MySpecialTokenR] % nicer for checker
+\def\DoWhatever{\ifx\NextToken\MySpecialTokenL YES\else NOP\fi : }
+\futurelet\NextToken\DoWhatever [A]\crlf
+\futurelet\NextToken\DoWhatever (A)\par
\stopbuffer
\typebuffer
-Unless a number is an unexpandable token it ends with a space or \prm {relax},
-so when you end up in the true branch, you'd better check if \TEX\ could
-determine where the number ends.
+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}
-% When comparing integers, definitions (for instance characters) that can be seen
-% as such, or any converter that produces a number (like the \type {`} or \prm
-% {number} the usual \type {=}, \type {<} or \type {>} can be used. However, in
-% \LUAMETATEX\ you can negate such a comparison by \type {!}: \type {!=}, \type
-% {!<} or \type {!>}. Successive \type {!} toggle the negation state.
+\stopoldprimitive
-On top of these \ASCII\ combinations, the engine also accepts some \UNICODE\
-characters. This brings the full repertoire to:
+\startoldprimitive[title={\prm {gdef}}]
-\starttabulate[|l|cT|cT|l|]
-\FL
-\BC character \BC \BC \BC operation \NC \NR
-\ML
-\NC \type {0x003C} \NC $\Uchar"003C$ \NC \NC less \NC \NR
-\NC \type {0x003D} \NC $\Uchar"003D$ \NC \NC equal \NC \NR
-\NC \type {0x003E} \NC $\Uchar"003E$ \NC \NC more \NC \NR
-\NC \type {0x2208} \NC $\Uchar"2208$ \NC \NC element of \NC \NR
-\NC \type {0x2209} \NC $\Uchar"2209$ \NC \NC not element of \NC \NR
-\NC \type {0x2260} \NC $\Uchar"2260$ \NC != \NC not equal \NC \NR
-\NC \type {0x2264} \NC $\Uchar"2264$ \NC !> \NC less equal \NC \NR
-\NC \type {0x2265} \NC $\Uchar"2265$ \NC !< \NC greater equal \NC \NR
-\NC \type {0x2270} \NC $\Uchar"2270$ \NC \NC not less equal \NC \NR
-\NC \type {0x2271} \NC $\Uchar"2271$ \NC \NC not greater equal \NC \NR
-\LL
-\stoptabulate
+The is the global companion of \prm {def}.
-This also applied to \prm {ifdim} although in the case of element we discard the
-fractional part (read: divide the numeric representation by 65536).
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {gdefcsname}}]
+
+As with standard \TEX\ we also define global ones:
+
+\starttyping
+\expandafter\gdef\csname MyMacro:1\endcsname{...}
+ \gdefcsname MyMacro:1\endcsname{...}
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {givenmathstyle}}]
+
+This primitive expects a math style and returns it when valid or otherwise issues
+an error.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {gleaders}}]
+
+Leaders are glue with special property: a box, rule of (in \LUAMETATEX) glyph, like:
+
+\startlines
+x\leaders \glyph `M \hfill x
+xx\leaders \glyph `M \hfill xx
+
+x\cleaders \glyph `M \hfill x
+xx\cleaders \glyph `M \hfill xx
+
+x\xleaders \glyph `M \hfill x
+xx\xleaders \glyph `M \hfill xx
+
+x\gleaders \glyph `M \hfill x
+xx\gleaders \glyph `M \hfill xx
+\stoplines
+
+Leaders fill the available space. The \prm {leaders} command starts at the left
+edge and stops when there is no more space. The blobs get centered when we use
+\prm {cleaders}: excess space is distributed before and after a blob while \prm
+{xleaders} also puts space between the blobs.
+
+When a rule is given the advance (width or height and depth) is ignored, so these
+are equivalent.
+
+\starttyping
+x\leaders \hrule \hfill x
+x\leaders \hrule width 1cm \hfill x
+\stoptyping
+
+When a box is used one will normally have some alignment in that box.
+
+\starttyping
+x\leaders \hbox {\hss.\hss} \hfill x
+x\leaders \hbox {\hss.\hss} \hskip 6cm \relax x
+\stoptyping
+
+The reference point is the left edge of the current (outer) box and the effective
+glue (when it has stretch or shrink) depends on that box. The \prm {gleaders}
+variant takes the page as reference. That makes it possible to \quote {align}
+across boxes.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glet}}]
+
+This is the global companion of \prm {let}. The fact that it is not an original
+primitive is probably due to the expectation for it not it not being used (as)
+often (as in \CONTEXT).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {gletcsname}}]
+
+Naturally \LUAMETATEX\ also provides a global variant:
+
+\starttyping
+\expandafter\global\expandafter\let\csname MyMacro:1\endcsname\relax
+\expandafter \glet\csname MyMacro:1\endcsname\relax
+ \gletcsname MyMacro:1\endcsname\relax
+\stoptyping
+
+So, here we save even more.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glettonothing}}]
+
+This is the global companion of \prm {lettonothing}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {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={\prm {ifdim}}]
+\startoldprimitive[title={\prm {globaldefs}}]
-Dimensions can be compared with this traditional \TEX\ primitive.
+When set to a positive value, this internal integer will force all definitions to
+be global, and in a complex macro package that is not something a user will do
+unless it is very controlled.
-\startbuffer
-\scratchdimen=1pt \scratchcounter=65536
+\stopoldprimitive
-\ifdim\scratchdimen=\scratchcounter sp YES \else NOP\fi
-\ifdim\scratchdimen=1 pt YES \else NOP\fi
-\stopbuffer
+\startoldprimitive[title={\prm {glueexpr}}]
-\typebuffer
+This is a more extensive variant of \prm {dimexpr} that also handles the optional
+stretch and shrink components.
-The units are mandate:
+\stopoldprimitive
-{\getbuffer}
+\startoldprimitive[title={\prm {glueshrink}}]
+
+This returns the shrink component of a glue quantity. The result is a dimension
+so you need to apply \prm {the} when applicable.
\stopoldprimitive
-\startoldprimitive[title={\prm {ifodd}}]
+\startoldprimitive[title={\prm {glueshrinkorder}}]
-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,
+This returns the shrink order of a glue quantity. The result is a integer so you
+need to apply \prm {the} when applicable.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {gluespecdef}}]
+
+A variant of \prm {integerdef} and \prm {dimensiondef} is:
+
+\starttyping
+\gluespecdef\MyGlue = 3pt plus 2pt minus 1pt
+\stoptyping
+
+The properties are comparable to the ones described in the previous sections.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {gluestretch}}]
+
+This returns the stretch component of a glue quantity. The result is a dimension
+so you need to apply \prm {the} when applicable.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {gluestretchorder}}]
+
+This returns the stretch order of a glue quantity. The result is a integer so you
+need to apply \prm {the} when applicable.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {gluetomu}}]
+
+The sequence \typ {\the \gluetomu 20pt plus 10pt minus 5pt} gives \the \gluetomu
+20pt plus 10pt minus 5pt.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {glyph}}]
+
+This is a more extensive variant of \prm {char} that permits setting some
+properties if the injected character node.
\startbuffer
-\ifodd65 YES \else NO\fi &
-\ifodd`B YES \else NO\fi .
+\ruledhbox{\glyph
+ scale 2000 xscale 9000 yscale 1200
+ slant 700 weight 200
+ xoffset 10pt yoffset -5pt left 10pt right 20pt
+ 123}
+\quad
+\ruledhbox{\glyph
+ scale 2000 xscale 9000 yscale 1200
+ slant 700 weight 200
+ 125}
\stopbuffer
\typebuffer
-So: {\inlinebuffer}
+In addition one can specify \type {font} (symbol), \type {id} (valid font id
+number), an \type {options} (bit set) and \type {raise}.
+
+\startlinecorrection
+\dontleavehmode\getbuffer
+\stoplinecorrection
+
+When no parameters are set, the current ones are used. More details and examples
+of usage can be found in the \CONTEXT\ distribution.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphdatafield}}]
+
+The value of this parameter is assigned to data field in glyph nodes that get
+injected. It has no meaning in itself but can be used at the \LUA\ end.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphoptions}}]
+
+The value of this parameter is assigned to the options field in glyph nodes that
+get injected.
+
+\startcolumns
+\getbuffer[engine:syntax:glyphoptions]
+\stopcolumns
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphscale}}]
+
+An integer parameter defining the current glyph scale, assigned to glyphs
+(characters) inserted into the current list.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphscriptfield}}]
+
+The value of this parameter is assigned to script field in glyph nodes that get
+injected. It has no meaning in itself but can be used at the \LUA\ end.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphscriptscale}}]
+
+This multiplier is applied to text font and glyph dimension properties when script
+style is used.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphscriptscriptscale}}]
+
+This multiplier is applied to text font and glyph dimension properties when
+script script style is used.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphslant}}]
+
+An integer parameter defining the current glyph slant, assigned to glyphs
+(characters) inserted into the current list.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphstatefield}}]
+
+The value of this parameter is assigned to script state in glyph nodes that get
+injected. It has no meaning in itself but can be used at the \LUA\ end.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphtextscale}}]
+
+This multiplier is applied to text font and glyph dimension properties when text
+style is used.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphweight}}]
+
+An integer parameter defining the current glyph weight, assigned to glyphs
+(characters) inserted into the current list.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphxoffset}}]
+
+An integer parameter defining the current glyph x offset, assigned to glyphs
+(characters) inserted into the current list. Normally this will only be set when
+one explicitly works with glyphs and defines a specific sequence.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphxscale}}]
+
+An integer parameter defining the current glyph x scale, assigned to glyphs
+(characters) inserted into the current list.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphxscaled}}]
+
+This primitive returns the given dimension scaled by the \prm {glyphscale} and
+\prm {glyphxscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphyoffset}}]
+
+An integer parameter defining the current glyph x offset, assigned to glyphs
+(characters) inserted into the current list. Normally this will only be set when
+one explicitly works with glyphs and defines a specific sequence.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphyscale}}]
+
+An integer parameter defining the current glyph y scale, assigned to glyphs
+(characters) inserted into the current list.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {glyphyscaled}}]
+
+This primitive returns the given dimension scaled by the \prm {glyphscale} and
+\prm {glyphyscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {gtoksapp}}]
+
+This is the global variant of \prm {toksapp}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {gtokspre}}]
+
+This is the global variant of \prm {tokspre}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {halign}}]
+
+This command starts horizontally aligned material. Macro packages use this
+command in table mechanisms and math alignments. It starts with a preamble
+followed by entries (rows and columns).
\stopoldprimitive
-\startoldprimitive[title={\prm {ifvmode}}]
+\startoldprimitive[title={\prm {hangafter}}]
-This traditional conditional checks we are in (internal) vertical mode.
+This parameter tells the par builder when indentation specified with \prm
+{hangindent} starts. A negative value does the opposite and starts indenting
+immediately. So, a value of $-2$ will make the first two lines indent.
\stopoldprimitive
-\startoldprimitive[title={\prm {ifhmode}}]
+\startoldprimitive[title={\prm {hangindent}}]
-This traditional conditional checks we are in (restricted) horizontal mode.
+This parameter relates to \prm {hangafter} and sets the amount of indentation.
+When larger than zero indentation happens left, otherwise it starts at the right
+edge.
\stopoldprimitive
-\startoldprimitive[title={\prm {ifmmode}}]
+\startoldprimitive[title={\prm {hbadness}}]
-This traditional conditional checks we are in (inline or display) math mode mode.
+This sets the threshold for reporting a horizontal badness value, its current
+value is \the \badness.
\stopoldprimitive
-\startoldprimitive[title={\prm {ifinner}}]
+\startoldprimitive[title={\prm {hbox}}]
-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.
+This constructs a horizontal box. There are a lot of optional parameters so more
+details can be found in dedicated manuals. When the content is packed a callback
+can kick in that can be used to apply for instance font features.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {hccode}}]
+
+The \TEX\ engine is good at hyphenating but traditionally that has been limited
+to hyphens. Some languages however use different characters. You can set up a
+different \prm {hyphenchar} as well as pre and post characters, but there's also
+a dedicated code for controlling this.
\startbuffer
-test \ifhmode \ifinner INNER\fi HMODE\fi\crlf
-\hbox{test \ifhmode \ifinner INNER \fi HMODE\fi} \par
+\hccode"2013 "2013
-\ifvmode \ifinner INNER\fi VMODE \fi\crlf
-\vbox{\ifvmode \ifinner INNER \fi VMODE\fi} \crlf
-\vbox{\ifinner INNER \ifvmode VMODE \fi \fi} \par
+\hsize 50mm test\char"2013test\par
+\hsize 1mm test\char"2013test\par
+
+\hccode"2013 `!
+
+\hsize 50mm test\char"2013test\par
+\hsize 1mm test\char"2013test\par
\stopbuffer
\typebuffer
-Watch the last line: because we typeset \type {INNER} we enter horizontal mode:
+This example shows that we can mark a character as hyphen|-|like but also can
+remap it to something else:
-{\getbuffer}
+\startpacked \getbuffer \stoppacked
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {hfil}}]
+
+This is a shortcut for \typ {\hskip plus 1 fil} (first order filler).
\stopoldprimitive
-\startoldprimitive[title={\prm {ifvoid}}]
+\startoldprimitive[title={\prm {hfill}}]
-This traditional conditional checks if a given box register or internal box
-variable has any content.
+This is a shortcut for \typ {\hskip plus 1 fill} (second order filler).
\stopoldprimitive
-\startoldprimitive[title={\prm {ifhbox}}]
+\startoldprimitive[title={\prm {hfilneg}}]
-This traditional conditional checks if a given box register or internal box
-variable represents a horizontal box,
+This is a shortcut for \typ {\hskip plus - 1 fil} so it can compensate \prm
+{hfil}.
\stopoldprimitive
-\startoldprimitive[title={\prm {ifvbox}}]
+\startoldprimitive[title={\prm {hfuzz}}]
-This traditional conditional checks if a given box register or internal box
-variable represents a vertical box,
+This dimension sets the threshold for reporting horizontal boxes that are under-
+or overfull. The current value is \the \hfuzz.
\stopoldprimitive
-\startoldprimitive[title={\prm {ifx}}]
+\startnewprimitive[title={\prm {hjcode}}]
-We use this traditional \TEX\ conditional a lot in \CONTEXT. Contrary to \prm {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.
+The so called lowercase code determines if a character is part of a
+to|-|be|-|hyphenated word. In \LUATEX\ we introduced the \quote {hyphenation
+justification} code as replacement. When a language is saved and no \prm {hjcode}
+is set the \prm {lccode} is used instead. This code serves a second purpose. When
+the assigned value is greater than 0 but less than 32 it indicated the to be used
+length when checking for left- and righthyphenmin. For instance it make sense to
+set the code to~2 for characters like Å“.
-Control sequences are identical when they have the same command code and
-character code. Because a \prm {let} macro is just a reference, both let macros
-are the same and equal to \prm {relax}:
+\stopnewprimitive
-\starttyping
-\let\one\relax \let\two\relax
-\stoptyping
+\startoldprimitive[title={\prm {hkern}}]
-The same is true for other definitions that result in the same (primitive) or
-meaning encoded in the character field (think of \prm {chardef}s and so).
+This primitive is like \prm {kern} but will force the engine into horizontal mode
+if it isn't yet.
\stopoldprimitive
-\startoldprimitive[title={\prm {ifeof}}]
+\startnewprimitive[title={\prm {hmcode}}]
-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.
+The \type {hm} stands for \quote {hyphenation math}. When bit~1 is set the
+characters will be repeated on the next line after a break. The second bit
+concerns italic correction but is of little relevance now that we moved to a
+different model in \CONTEXT. Here are some examples, we also show an example of
+\prm {mathdiscretionary} because that is what this code triggers:
-\stopoldprimitive
+\startbuffer
+test $ \dorecurse {50} {
+ a \discretionary class 2 {$\darkred +$}{$\darkgreen +$}{$\darkblue +$}
+} b$
-\startoldprimitive[title={\prm {iftrue}}]
+test $ a \mathdiscretionary class 1 {-}{-}{-} b$
-Here we have a traditional \TEX\ conditional that is always true (therefore the
-same is true for any macro that is \prm {let} to this primitive).
+\bgroup
+ \hmcode"002B=1 % +
+ \hmcode"002D=1 % -
+ \hmcode"2212=1 % -
+ test $ \dorecurse{50}{a + b - } c$
+\egroup
+\stopbuffer
+
+\typebuffer
+
+{\setuptolerance[verytolerant,stretch]\getbuffer}
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {holdinginserts}}]
+
+When set to a positive value inserts will be kept in the stream and not moved to
+the insert registers.
\stopoldprimitive
-\startoldprimitive[title={\prm {iffalse}}]
+\startnewprimitive[title={\prm {holdingmigrations}}]
-Here we have a traditional \TEX\ conditional that is always false (therefore the
-same is true for any macro that is \prm {let} to this primitive).
+When set to a positive value marks (and adjusts) will be kept in the stream and
+not moved to the outer level or related registers.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {hpack}}]
+
+This primitive is like \prm {hbox} but without the callback overhead.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {hpenalty}}]
+
+This primitive is like \prm {penalty} but will force the engine into horizontal
+mode if it isn't yet.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {hrule}}]
+
+This creates a horizontal rule. Unless the width is set it will stretch to fix
+the available width. In addition to the traditional \type {width}, \type {height}
+and \type {depth} specifiers some more are accepted. These are discussed in other
+manuals. To give an idea:
+
+\startbuffer
+h\hrule width 10mm height 2mm depth 1mm \relax rule
+h\hrule width 10mm height 2mm depth 1mm xoffset 30mm yoffset -10mm \relax rule
+v\vrule width 10mm height 2mm depth 1mm \relax rule
+v\vrule width 10mm height 2mm depth 1mm xoffset 30mm yoffset 10mm \relax rule
+\stopbuffer
+
+\typebuffer
+
+The \prm {relax} stops scanning and because we have more keywords we get a
+different error report than in traditional \TEX\ when a lookahead confuses the
+engine. On separate lines we get the following.
+
+\startlines
+\getbuffer
+\stoplines
\stopoldprimitive
-\startoldprimitive[title={\prm {ifcase}}]
+\startoldprimitive[title={\prm {hsize}}]
-This numeric \TEX\ conditional takes a counter (literal, register, shortcut to a
-character, internal quantity) and goes to the branch that matches.
+This sets (or gets) the current horizontal size.
\startbuffer
-\ifcase 3 zero\or one\or two\or three\or four\else five or more\fi
+\hsize 40pt \setbox0\vbox{x} hsize: \the\wd0
+\setbox0\vbox{\hsize 40pt x} hsize: \the\wd0
\stopbuffer
\typebuffer
-Indeed: \inlinebuffer\ equals three. In later sections we will see some
-\LUAMETATEX\ primitives that behave like an \prm {ifcase}.
+In both cases we get the same size reported but the first one will also influence
+the current paragraph when used ungrouped.
+
+\startlines
+\getbuffer
+\stoplines
\stopoldprimitive
-\startoldprimitive[title={\prm {ifdefined}}]
+\startoldprimitive[title={\prm {hskip}}]
-In traditional \TEX\ checking for a macro to exist was a bit tricky and therefore
-\ETEX\ introduced a convenient conditional. We can do this:
+The given glue is injected in the horizontal list. If possible horizontal mode is
+entered.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {hss}}]
+
+\startbuffer
+x\hbox to 0pt{\hskip 0pt plus 1 fil minus 1 fil\relax test}x
+x\hbox to 0pt{\hss test}x
+x\hbox to 0pt{test\hskip 0pt plus 1 fil minus 1 fil\relax}x
+x\hbox to 0pt{test\hss}x
+\stopbuffer
+
+In traditional \TEX\ glue specifiers are shared. This makes a lot of sense when
+memory has to be saved. For instance spaces in a paragraph of text are often the
+same and a glue specification has at least an amount, stretch, shrink, stretch
+order and shrink order field plus a leader pointer; in \LUAMETATEX\ we have even
+more fields. In \LUATEX\ these shared (and therefore referenced) glue spec nodes
+became just copies.
+
+\typebuffer
+
+The \prm {hss} primitives injects a glue node with one order stretch and one
+order shrink. In traditional \TEX\ this is a reference to a shared specification,
+and in \LUATEX\ just a copy of a predefined specifier. The only gain is now in
+tokens because one could just be explicit or use a glue register with that value
+because we have plenty glue registers.
+
+\startlines
+\getbuffer
+\stoplines
+
+We could have this:
\starttyping
-\ifx\MyMacro\undefined ... \else ... \fi
+\permanent\protected\untraced\def\hss
+ {\hskip0pt plus 1 fil minus 1 fil\relax}
\stoptyping
-but that assumes that \type {\undefined} is indeed undefined. Another test often
-seen was this:
+or this:
\starttyping
-\expandafter\ifx\csname MyMacro\endcsname\relax ... \else ... \fi
+\gluespecdef\hssglue 0pt plus 1 fil minus 1 fil
+
+\permanent\protected\untraced\def\hss
+ {\hskip\hssglue}
\stoptyping
-Instead of comparing with \type {\undefined} we need to check with \prm {relax}
-because the control sequence is defined when not yet present and defaults to
-\prm {relax}. This is not pretty.
+but we just keep the originals around.
\stopoldprimitive
-\startoldprimitive[title={\prm {ifcsname}}]
+\startoldprimitive[title={\prm {ht}}]
-This is an \ETEX\ conditional that complements the one on the previous section:
+Returns the height of the given box.
-\starttyping
-\expandafter\ifx\csname MyMacro\endcsname\relax ... \else ... \fi
- \ifcsname MyMacro\endcsname ... \else ... \fi
-\stoptyping
+\stopoldprimitive
-Here the first one has the side effect of defining the macro and defaulting it to
-\prm {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.
+\startoldprimitive[title={\prm {hyphenation}}]
-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 \prm
-{endcsname} are gobbled.
+The list passed to this primitive contains hyphenation exceptions that get bound
+to the current language. In \LUAMETATEX\ this can be managed at the \LUA\ end.
+Exceptions are not stored in the format file.
\stopoldprimitive
-\startoldprimitive[title={\prm {iffontchar}}]
+\startnewprimitive[title={\prm {hyphenationmin}}]
-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.
+This property (that also gets bond to the current language) sets the minimum
+length of a word that gets hyphenated.
+
+\stopnewprimitive
+
+% \startnewprimitive[title={\prm {hyphenationmode}}]
+% \stopnewprimitive
+
+\startoldprimitive[title={\prm {hyphenchar}}]
+
+This is one of the font related primitives: it returns the number of the hyphen
+set in the given font.
\stopoldprimitive
-\startnewprimitive[title={\prm {ifincsname}}]
+\startoldprimitive[title={\prm {hyphenpenalty}}]
-This conditional is sort of obsolete and can be used to check if we're inside a
-\prm {csname} or \prm {ifcsname} construction. It's not used in \CONTEXT.
+Discretionary nodes have a related default penalty. The \prm {hyphenpenalty} is
+injected after a regular discretionary, and \prm {exhyphenpenalty} after \type
+{\-} or \type {-}. The later case is called an automatic discretionary. In
+\LUAMETATEX\ we have two extra penalties: \prm {explicithyphenpenalty} and \prm
+{automatichyphenpenalty} and these are used when the related bits are set in \prm
+{hyphenationmode}.
-\stopnewprimitive
+\stopoldprimitive
-\startnewprimitive[title={\prm {ifabsnum}}]
+\startoldprimitive[title={\prm {if}}]
-This test will negate negative numbers before comparison, as in:
+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\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}
+\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]
-\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}\par
\stopbuffer
\typebuffer
-Here we get the same result each time:
+The last example demonstrates that the tokens get expanded, which is why
+we get the extra \type {A}:
{\getbuffer}
-\stopnewprimitive
+\stopoldprimitive
\startnewprimitive[title={\prm {ifabsdim}}]
@@ -1555,220 +5009,234 @@ So we get this:
\stopnewprimitive
-\startnewprimitive[title={\prm {ifzerodim}}]
+\startnewprimitive[title={\prm {ifabsfloat}}]
-This tests for a dimen (dimension) being zero so we have:
+This test will negate negative floats before comparison, as in:
-\starttyping
-\ifdim<dimension>=0pt
-\ifzerodim<dimension>
-\ifcase<dimension register>
-\stoptyping
+\startbuffer
+\def\TestA#1{\iffloat #1<2.46 small\orelse\iffloat #1>4.68 large\else medium\fi}
+\def\TestB#1{\ifabsfloat#1<2.46 small\orelse\ifabsfloat#1>4.68 large\else medium\fi}
-\stopnewprimitive
+\TestA {1.23}\quad\TestA {3.45}\quad\TestA {5.67}\crlf
+\TestB {1.23}\quad\TestB {3.45}\quad\TestB {5.67}\crlf
+\TestB{-1.23}\quad\TestB{-3.45}\quad\TestB{-5.67}\par
+\stopbuffer
-\startnewprimitive[title={\prm {ifzeronum}}]
+\typebuffer
-This tests for a number (integer) being zero so we have these variants now:
+So we get this:
-\starttyping
-\ifnum<integer or equivalent>=0pt
-\ifzeronum<integer or equivalent>
-\ifcase<integer or equivalent>
-\stoptyping
+{\getbuffer}
\stopnewprimitive
-\startnewprimitive[title={\prm {ifchknum}}]
+\startnewprimitive[title={\prm {ifabsnum}}]
-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:
+This test will negate negative numbers before comparison, as in:
\startbuffer
-\ifchknum oeps\or okay\else error\fi\quad
-\ifchknum 12 \or okay\else error\fi\quad
-\ifchknum 12pt\or okay\else error\fi
+\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}\par
\stopbuffer
\typebuffer
-The result is as expected:
+Here we get the same result each time:
{\getbuffer}
\stopnewprimitive
-\startnewprimitive[title={\prm {ifchkdim}}]
+\startnewprimitive[title={\prm {ifarguments}}]
-A variant on the checker in the previous section is a dimension checker:
+This is a variant of \prm {ifcase} were the selector is the number of arguments
+picked up. For example:
\startbuffer
-\ifchkdim oeps\or okay\else error\fi\quad
-\ifchkdim 12 \or okay\else error\fi\quad
-\ifchkdim 12pt\or okay\else error\fi
+\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}\par
\stopbuffer
\typebuffer
-We get:
+Watch the non counted, ignored, argument in the last case. Normally this test will
+be used in combination with \prm {ignorearguments}.
{\getbuffer}
\stopnewprimitive
-\startnewprimitive[title={\prm {ifcmpnum}}]
+\startnewprimitive[title={\prm {ifboolean}}]
-This conditional compares two numbers and the resulting \prm {ifcase} reflects
-their relation:
+This tests a number (register or equivalent) and any nonzero value represents
+\type {true}, which is nicer than using an \type {\unless \ifcase}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {ifcase}}]
+
+This numeric \TEX\ conditional takes a counter (literal, register, shortcut to a
+character, internal quantity) and goes to the branch that matches.
\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]
+\ifcase 3 zero\or one\or two\or three\or four\else five or more\fi
\stopbuffer
\typebuffer
-This gives:
-
-{\getbuffer}
+Indeed: \inlinebuffer\ equals three. In later sections we will see some
+\LUAMETATEX\ primitives that behave like an \prm {ifcase}.
-\stopnewprimitive
+\stopoldprimitive
-\startnewprimitive[title={\prm {ifcmpdim}}]
+\startoldprimitive[title={\prm {ifcat}}]
-This conditional compares two dimensions and the resulting \prm {ifcase}
-reflects their relation:
+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
-[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]
+\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
-This gives:
+Close reading is needed here:
{\getbuffer}
-\stopnewprimitive
+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.
-\startnewprimitive[title={\prm {ifnumval}}]
+\stopoldprimitive
-This conditional is a variant on \prm {ifchknum}. This time we get
-some more detail about the value:
+\startnewprimitive[title={\prm {ifchkdim}}]
+
+A variant on the checker in the previous section is a dimension checker:
\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]
+\ifchkdim oeps \or okay\else error\fi\quad
+\ifchkdim 12 \or okay\else error\fi\quad
+\ifchkdim 12pt \or okay\else error\fi\quad
+\ifchkdim 12pt or more\or okay\else error\fi
\stopbuffer
\typebuffer
-This gives:
+We get:
{\getbuffer}
\stopnewprimitive
-\startnewprimitive[title={\prm {ifdimval}}]
+\startnewprimitive[title={\prm {ifchkdimension}}]
-This conditional is a variant on \prm {ifchkdim} and provides some more
-detailed information about the value:
+COntrary to \prm {ifchkdim} this test doesn't accept trailing crap:
\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]
+\ifchkdimension oeps \or okay\else error\fi\quad
+\ifchkdimension 12 \or okay\else error\fi\quad
+\ifchkdimension 12pt \or okay\else error\fi\quad
+\ifchkdimension 12pt or more\or okay\else error\fi
\stopbuffer
\typebuffer
-This gives:
+reports:
{\getbuffer}
\stopnewprimitive
-\startnewprimitive[title={\prm {iftok}}]
+\startnewprimitive[title={\prm {ifchknum}}]
-When you want to compare two arguments, the usual way to do this is the
-following:
+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:
-\starttyping
-\edef\tempA{#1}
-\edef\tempb{#2}
-\ifx\tempA\tempB
- the same
-\else
- different
-\fi
-\stoptyping
+\startbuffer
+\ifchknum oeps \or okay\else error\fi\quad
+\ifchknum 12 \or okay\else error\fi\quad
+\ifchknum 12pt \or okay\else error\fi\quad
+\ifchknum 12pt or more\or okay\else error\fi
+\stopbuffer
-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:
+\typebuffer
-\starttyping
-\iftok{#1}{#2}
- the same
-\else
- different
-\fi
-\stoptyping
+The result is as expected:
-Instead of direct list you can also pass registers, so given:
+{\getbuffer}
-\startbuffer[a]
-\scratchtoks{a}%
-\toks0{a}%
-\stopbuffer
+\stopnewprimitive
-\typebuffer[a]
+\startnewprimitive[title={\prm {ifchknumber}}]
-This:
+This check is more restrictive than \prm {ifchknum} discussed in the previous
+section:
-\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
+\startbuffer
+\ifchknumber oeps \or okay\else error\fi\quad
+\ifchknumber 12 \or okay\else error\fi\quad
+\ifchknumber 12pt \or okay\else error\fi\quad
+\ifchknumber 12pt or more\or okay\else error\fi
\stopbuffer
-\typebuffer[b]
+\typebuffer
-{\getbuffer[a]gives: \inlinebuffer[b].}
+Here we get:
+
+{\getbuffer}
\stopnewprimitive
-\startnewprimitive[title={\prm {ifcstok}}]
+\startnewprimitive[title={\prm {ifcmpdim}}]
-A variant on the primitive mentioned in the previous section is one that
-operates on lists and macros:
+This conditional compares two dimensions and the resulting \prm {ifcase}
+reflects their relation:
-\startbuffer[a]
-\def\a{a} \def\b{b} \def\c{a}
+\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[a]
+\typebuffer
-\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
+This gives:
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ifcmpnum}}]
+
+This conditional compares two numbers and the resulting \prm {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
-This:
+\typebuffer
-\typebuffer[b]
+This gives:
-{\getbuffer[a]will give us: \inlinebuffer[b].}
+{\getbuffer}
\stopnewprimitive
@@ -1840,43 +5308,144 @@ is also okay. Now, is that neat or not?
\stopnewprimitive
-\startnewprimitive[title={\prm {iffrozen}}]
+\startnewprimitive[title={\prm {ifcramped}}]
-This conditional checks if a control sequence is frozen:
+Depending on the given math style this returns true of false:
-\starttyping
-is \iffrozen\MyMacro \else not \fi frozen
-\stoptyping
+\startbuffer
+\ifcramped\mathstyle no \fi
+\ifcramped\crampedtextstyle yes \fi
+\ifcramped\textstyle no \fi
+\ifcramped\displaystyle yes \fi
+\stopbuffer
+
+\typebuffer
+
+gives: \inlinebuffer.
\stopnewprimitive
-\startnewprimitive[title={\prm {ifprotected}}]
+\startoldprimitive[title={\prm {ifcsname}}]
-This conditional checks if a control sequence is protected:
+This is an \ETEX\ conditional that complements the one on the previous section:
\starttyping
-is \ifprotected\MyMacro \else not \fi protected
+\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
+\prm {relax}, while the second one doesn't do that. Just 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 \prm
+{endcsname} are gobbled.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {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={\prm {ifusercmd}}]
+\startoldprimitive[title={\prm {ifdefined}}]
-This conditional checks if a control sequence is not one of the primitives:
+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
-is \ifusercmd\MyMacro \else not \fi a primitive
+\ifx\MyMacro\undefined ... \else ... \fi
\stoptyping
-It is not always possible to determine this but it should work okay for regular
-macros, register allocations and character definitions.
+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 \prm {relax}
+because the control sequence is defined when not yet present and defaults to
+\prm {relax}. This is not pretty.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {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
+
+\startnewprimitive[title={\prm {ifdimexpression}}]
+
+The companion of the previous primitive is:
+
+\startbuffer
+\ifdimexpression 10pt > 10bp \relax
+ do-something
+\fi
+\stopbuffer
+
+This matches when the result is non zero, and you can mix calculations and tests
+as with normal expressions. Contrary to the number variant units can be used and
+precision kicks in.
\stopnewprimitive
-\startnewprimitive[title={\prm {ifrelax}}]
+\startnewprimitive[title={\prm {ifdimval}}]
-This is a convenient shortcut for \typ {\ifx\relax} and the motivation for adding
-this one is (as with some others) to get less tracing.
+This conditional is a variant on \prm {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
@@ -1908,64 +5477,98 @@ Of course this is not empty at all:
\stopnewprimitive
-\startnewprimitive[title={\prm {ifboolean}}]
+\startoldprimitive[title={\prm {iffalse}}]
-This tests a number (register or equivalent) and any nonzero value represents
-\type {true}, which is nicer than using an \type {\unless \ifcase}.
+Here we have a traditional \TEX\ conditional that is always false (therefore the
+same is true for any macro that is \prm {let} to this primitive).
-\stopnewprimitive
+\stopoldprimitive
-\startnewprimitive[title={\prm {ifmathparameter}}]
+\startnewprimitive[title={\prm {ifflags}}]
-This is an \prm {ifcase} where the value depends on if the given math parameter
-is zero, (\type {0}), set (\type {1}), or unset (\type {2}).
+This test primitive relates to the various flags that one can set on a control
+sequence in the perspective of overload protection and classification.
-\starttyping
-\ifmathparameter\Umathpunctclosespacing\displaystyle
- zero \or
- nonzero \or
- unset \fi
-\stoptyping
+\startbuffer
+\protected\untraced\tolerant\def\foo[#1]{...#1...}
+\permanent\constant \def\oof{okay}
+\stopbuffer
-\stopnewprimitive
+\typebuffer
-\startnewprimitive[title={\prm {ifmathstyle}}]
+\start \getbuffer
+\starttabulate[|l|c|c|l|c|c|]
+\FL
+\NC flag \NC \type {\foo} \NC \type {\oof}
+\NC flag \NC \type {\foo} \NC \type {\oof} \NC \NR
+\ML
+\NC frozen \NC \ifflags\foo\frozen Y\else N\fi \NC \ifflags\oof\frozen Y\else N\fi
+\NC permanent \NC \ifflags\foo\permanent Y\else N\fi \NC \ifflags\oof\permanent Y\else N\fi \NC \NR
+\NC immutable \NC \ifflags\foo\immutable Y\else N\fi \NC \ifflags\oof\immutable Y\else N\fi
+\NC mutable \NC \ifflags\foo\mutable Y\else N\fi \NC \ifflags\oof\mutable Y\else N\fi \NC \NR
+\NC noaligned \NC \ifflags\foo\noaligned Y\else N\fi \NC \ifflags\oof\noaligned Y\else N\fi
+\NC instance \NC \ifflags\foo\instance Y\else N\fi \NC \ifflags\oof\instance Y\else N\fi \NC \NR
+\NC untraced \NC \ifflags\foo\untraced Y\else N\fi \NC \ifflags\oof\untraced Y\else N\fi
+\NC global \NC \ifflags\foo\global Y\else N\fi \NC \ifflags\oof\global Y\else N\fi \NC \NR
+\NC tolerant \NC \ifflags\foo\tolerant Y\else N\fi \NC \ifflags\oof\tolerant Y\else N\fi
+\NC constant \NC \ifflags\foo\constant Y\else N\fi \NC \ifflags\oof\constant Y\else N\fi \NC \NR
+\NC protected \NC \ifflags\foo\protected Y\else N\fi \NC \ifflags\oof\protected Y\else N\fi
+\NC semiprotected \NC \ifflags\foo\semiprotected Y\else N\fi \NC \ifflags\oof\semiprotected Y\else N\fi \NC \NR
+\LL
+\stoptabulate
+\stop
-This is a variant of \prm {ifcase} were the number is one of the seven possible
-styles: display, text, cramped text, script, cramped script, script script,
-cramped script script.
+Instead of checking against a prefix you can test against a bitset made from:
-\starttyping
-\ifmathstyle
- display
-\or
- text
-\or
- cramped text
-\else
- normally smaller than text
-\fi
-\stoptyping
+\startluacode
+context.starttabulate { "|r|l|r|l|r|l|r|l|" }
+local n = 4
+for k, v in table.sortedhash(tex.flagcodes) do
+ if tonumber(k) then
+ n = n - 1
+ context.NC() context("0x%X",k)
+ context.NC() context(v)
+ if n == 0 then
+ context.NC()
+ context.NR()
+ n = 4
+ end
+ end
+end
+context.stoptabulate()
+\stopluacode
\stopnewprimitive
-\startnewprimitive[title={\prm {ifarguments}}]
+\startnewprimitive[title={\prm {iffloat}}]
-This is a variant of \prm {ifcase} were the selector is the number of arguments
-picked up. For example:
+This test does for floats what \prm {ifnum}, \prm {ifdim} do for numbers and
+dimensions: comparing two of them.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {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={\prm {ifhaschar}}]
+
+This one is a simplified variant of the above:
\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}\par
+\ifhaschar !{this ! works} yes \else no \fi
\stopbuffer
\typebuffer
-Watch the non counted, ignored, argument in the last case. Normally this test will
-be used in combination with \prm {ignorearguments}.
-
-{\getbuffer}
+and indeed we get: \inlinebuffer ! Of course the spaces in this this example
+code are normally not present in such a test.
\stopnewprimitive
@@ -2065,21 +5668,191 @@ ok:
\stopnewprimitive
-\startnewprimitive[title={\prm {ifhaschar}}]
+\startoldprimitive[title={\prm {ifhbox}}]
-This one is a simplified variant of the above:
+This traditional conditional checks if a given box register or internal box
+variable represents a horizontal box,
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {ifhmode}}]
+
+This traditional conditional checks we are in (restricted) horizontal mode.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {ifinalignment}}]
+
+As the name indicates, this primitive tests for being in an alignment. Roughly
+spoken, the engine is either in a state of align, handling text or dealing with
+math.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ifincsname}}]
+
+This conditional is sort of obsolete and can be used to check if we're inside a
+\prm {csname} or \prm {ifcsname} construction. It's not used in \CONTEXT.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {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
-\ifhaschar !{this ! works} yes \else no \fi
+test \ifhmode \ifinner INNER\fi HMODE\fi\crlf
+\hbox{test \ifhmode \ifinner INNER \fi HMODE\fi} \par
+
+\ifvmode \ifinner INNER\fi VMODE \fi\crlf
+\vbox{\ifvmode \ifinner INNER \fi VMODE\fi} \crlf
+\vbox{\ifinner INNER \ifvmode VMODE \fi \fi} \par
\stopbuffer
\typebuffer
-and indeed we get: \inlinebuffer ! Of course the spaces in this this example
-code are normally not present in such a test.
+Watch the last line: because we typeset \type {INNER} we enter horizontal mode:
+
+{\getbuffer}
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {ifinsert}}]
+
+This is the equivalent of \prm {ifvoid} for a given insert class.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ifintervaldim}}]
+
+This conditional is true when the intervals around the values of two dimensions
+overlap. The first dimension determines the interval.
+
+\startbuffer
+[\ifintervaldim1pt 20pt 21pt \else no \fi overlap]
+[\ifintervaldim1pt 18pt 20pt \else no \fi overlap]
+\stopbuffer
+
+\typebuffer
+
+So here: \inlinebuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ifintervalfloat}}]
+
+This one does with floats what we described under \prm {ifintervaldim}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ifintervalnum}}]
+
+This one does with integers what we described under \prm {ifintervaldim}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {iflastnamedcs}}]
+
+When a \prm {csname} is constructed and succeeds the last one is remembered and
+can be accessed with \prm {lastnamedcs}. It can however be an undefined one. That
+state can be checked with this primitive. Of course it also works with the \prm
+{ifcsname} and \prm {begincsname} variants.
\stopnewprimitive
+\startnewprimitive[title={\prm {ifmathparameter}}]
+
+This is an \prm {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={\prm {ifmathstyle}}]
+
+This is a variant of \prm {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
+
+\startoldprimitive[title={\prm {ifmmode}}]
+
+This traditional conditional checks we are in (inline or display) math mode mode.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {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 \prm {relax},
+so when you end up in the true branch, you'd better check if \TEX\ could
+determine where the number ends.
+
+{\getbuffer}
+
+% When comparing integers, definitions (for instance characters) that can be seen
+% as such, or any converter that produces a number (like the \type {`} or \prm
+% {number} the usual \type {=}, \type {<} or \type {>} can be used. However, in
+% \LUAMETATEX\ you can negate such a comparison by \type {!}: \type {!=}, \type
+% {!<} or \type {!>}. Successive \type {!} toggle the negation state.
+
+On top of these \ASCII\ combinations, the engine also accepts some \UNICODE\
+characters. This brings the full repertoire to:
+
+\starttabulate[|l|cT|cT|l|]
+\FL
+\BC character \BC \BC \BC operation \NC \NR
+\ML
+\NC \type {0x003C} \NC $\Uchar"003C$ \NC \NC less \NC \NR
+\NC \type {0x003D} \NC $\Uchar"003D$ \NC \NC equal \NC \NR
+\NC \type {0x003E} \NC $\Uchar"003E$ \NC \NC more \NC \NR
+\NC \type {0x2208} \NC $\Uchar"2208$ \NC \NC element of \NC \NR
+\NC \type {0x2209} \NC $\Uchar"2209$ \NC \NC not element of \NC \NR
+\NC \type {0x2260} \NC $\Uchar"2260$ \NC != \NC not equal \NC \NR
+\NC \type {0x2264} \NC $\Uchar"2264$ \NC !> \NC less equal \NC \NR
+\NC \type {0x2265} \NC $\Uchar"2265$ \NC !< \NC greater equal \NC \NR
+\NC \type {0x2270} \NC $\Uchar"2270$ \NC \NC not less equal \NC \NR
+\NC \type {0x2271} \NC $\Uchar"2271$ \NC \NC not greater equal \NC \NR
+\LL
+\stoptabulate
+
+This also applied to \prm {ifdim} although in the case of element we discard the
+fractional part (read: divide the numeric representation by 65536).
+
+\stopoldprimitive
+
\startnewprimitive[title={\prm {ifnumexpression}}]
Here is an example of a conditional using expressions:
@@ -2095,70 +5868,3114 @@ as with normal expressions.
\stopnewprimitive
-\startnewprimitive[title={\prm {ifdimexpression}}]
+\startnewprimitive[title={\prm {ifnumval}}]
-The companion of the previous primitive is:
+This conditional is a variant on \prm {ifchknum}. This time we get
+some more detail about the value:
\startbuffer
-\ifdimexpression 10pt > 10bp \relax
- do-something
+[-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
+
+\startoldprimitive[title={\prm {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
+
+\startnewprimitive[title={\prm {ifparameter}}]
+
+In a macro body \type {#1} is a reference to a parameter. You can check if one is
+set using a dedicated parameter condition:
+
+\startbuffer
+\tolerant\def\foo[#1]#*[#2]%
+ {\ifparameter#1\or one\else no one\fi\enspace
+ \ifparameter#2\or two\else no two\fi\emspace}
+
+\foo
+\foo[1]
+\foo[1][2]
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\getbuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ifparameters}}]
+
+This is equivalent to an \prm {ifcase} with as value the number of parameters
+passed to the current macro.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ifrelax}}]
+
+This is a convenient shortcut for \typ {\ifx\relax} and the motivation for adding
+this one is (as with some others) to get less tracing.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {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
-This matches when the result is non zero, and you can mix calculations and tests
-as with normal expressions. Contrary to the number variant units can be used and
-precision kicks in.
+\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
-\startoldprimitive[title={\prm {else}}]
+\startoldprimitive[title={\prm {iftrue}}]
-This traditional primitive is part of the condition testing mechanism. When a
-condition matches, \TEX\ will continue till it sees an \prm {else} or \prm
-{or} or \prm {orelse} (to be discussed later). It will then do a fast skipping
-pass till it sees an \prm {fi}.
+Here we have a traditional \TEX\ conditional that is always true (therefore the
+same is true for any macro that is \prm {let} to this primitive).
\stopoldprimitive
-\startoldprimitive[title={\prm {or}}]
+\startoldprimitive[title={\prm {ifvbox}}]
-This traditional primitive is part of the condition testing mechanism and relates
-to an \prm {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
-\prm {or} is seen, then it will continue expanding till it sees a \prm {or}
-or \prm {else} or \prm {orelse} (to be discussed later). It will then do a
-fast skipping pass till it sees an \prm {fi}.
+This traditional conditional checks if a given box register or internal box
+variable represents a vertical box,
\stopoldprimitive
-\startoldprimitive[title={\prm {fi}}]
+\startoldprimitive[title={\prm {ifvmode}}]
-This traditional primitive is part of the condition testing mechanism and ends a
-test. So, we have:
+This traditional conditional checks we are in (internal) vertical mode.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {ifvoid}}]
+
+This traditional conditional checks if a given box register or internal box
+variable has any content.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {ifx}}]
+
+We use this traditional \TEX\ conditional a lot in \CONTEXT. Contrary to \prm {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 \prm {let} macro is just a reference, both let macros
+are the same and equal to \prm {relax}:
\starttyping
-\ifsomething ... \else ... \fi
-\ifsomething ... \or ... \or ... \else ... \fi
-\ifsomething ... \orelse \ifsometing ... \else ... \fi
-\ifsomething ... \or ... \orelse \ifsometing ... \else ... \fi
+\let\one\relax \let\two\relax
\stoptyping
-The \prm {orelse} is new in \LUAMETATEX\ and a continuation like we find in
-other programming languages (see later section).
+The same is true for other definitions that result in the same (primitive) or
+meaning encoded in the character field (think of \prm {chardef}s and so).
\stopoldprimitive
-\startoldprimitive[title={\prm {unless}}]
+\startnewprimitive[title={\prm {ifzerodim}}]
-This \ETEX\ prefix will negate the test (when applicable).
+This tests for a dimen (dimension) being zero so we have:
\starttyping
- \ifx\one\two YES\else NO\fi
-\unless\ifx\one\two NO\else YES\fi
+\ifdim<dimension>=0pt
+\ifzerodim<dimension>
+\ifcase<dimension register>
\stoptyping
-This primitive is hardly used in \CONTEXT\ and we probably could get rid of these
-few cases.
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ifzerofloat}}]
+
+As the name indicated, this tests for a zero float value.
+
+\startbuffer
+[\scratchfloat\zerofloat \ifzerofloat\scratchfloat \else not \fi zero]
+[\scratchfloat\plusone \ifzerofloat\scratchfloat \else not \fi zero]
+[\scratchfloat 0.01 \ifzerofloat\scratchfloat \else not \fi zero]
+[\scratchfloat 0.0e0 \ifzerofloat\scratchfloat \else not \fi zero]
+[\scratchfloat \zeropoint\ifzerofloat\scratchfloat \else not \fi zero]
+\stopbuffer
+
+\typebuffer
+
+So: \inlinebuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ifzeronum}}]
+
+This tests for a number (integer) being zero so we have these variants now:
+
+\starttyping
+\ifnum<integer or equivalent>=0
+\ifzeronum<integer or equivalent>
+\ifcase<integer or equivalent>
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {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 \par
+\stopbuffer
+
+\typebuffer
+
+{\getbuffer}
+
+{\em Todo: explain optional delimiters.}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ignoredepthcriterion}}]
+
+When setting the \prm {prevdepth} (either by \TEX\ or by the current user) of the
+current vertical list the value 1000pt is a signal for special treatment of the
+skip between \quote {lines}. There is an article on that in the distribution. It
+also demonstrates that \prm {ignoredepthcriterion} can be used to change this
+special signal, just in case it is needed.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ignorenestedupto}}]
+
+This primitive gobbles following tokens and can deal with nested \quote
+{environments}, for example:
+
+\startbuffer
+\def\startfoo{\ignorenestedupto\startfoo\stopfoo}
+
+(before
+\startfoo
+ test \startfoo test \stopfoo
+ {test \startfoo test \stopfoo}
+\stopfoo
+after)
+\stopbuffer
+
+\typebuffer
+
+delivers:
+
+\getbuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ignorepars}}]
+
+This is a variant of \prm {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 \prm {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 \prm {par} tokens (and
+\CONTEXT\ set them such that this is the case).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {ignorerest}}]
+
+An example shows what this primitive does:
+
+\startbuffer
+\tolerant\def\foo[#1]#*[#2]%
+ {1234
+ \ifparameter#1\or\else
+ \expandafter\ignorerest
+ \fi
+ /#1/
+ \ifparameter#2\or\else
+ \expandafter\ignorerest
+ \fi
+ /#2/ }
+
+\foo test \foo[456] test \foo[456][789] test
+\stopbuffer
+
+\typebuffer
+
+As this likely makes most sense in conditionals you need to make sure the current
+state is properly finished. Because \prm {expandafter} bumps the input state,
+here we actually quit two levels; this is because so called \quote {backed up
+text} is intercepted by this primitive.
+
+\getbuffer
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {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={\prm {ignoreupto}}]
+
+This ignores everything upto the given token, so
+
+\startbuffer
+\ignoreupto \foo not this but\foo only this
+\stopbuffer
+
+\typebuffer
+
+will give: \inlinebuffer .
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {immediate}}]
+
+This one has no effect unless you intercept it at the \LUA\ end and act upon it.
+In original \TEX\ immediate is used in combination with read from and write to
+file operations. So, this is an old primitive with a new meaning.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {immutable}}]
+
+This prefix flags what follows as being frozen and is usually applied to for
+instance \prm {integerdef}'d control sequences. In that respect is is like \prm
+{permanent} but it makes it possible to distinguish quantities from macros.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {indent}}]
+
+In engines other than \LUAMETATEX\ a paragraph starts with an indentation box.
+The width of that (empty) box is determined by \prm {parindent}. In \LUAMETATEX\
+we can use a dedicated indentation skip instead (as part of paragraph
+normalization). An indentation can be zero'd with \prm {undent}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {indexofcharacter}}]
+
+This primitive is more versatile variant of the backward quote operator, so
+instead of:
+
+\starttyping
+\number`|
+\number`~
+\number`\a
+\number`\q
+\stoptyping
+
+you can say:
+
+\starttyping
+\the\indexofcharacter |
+\the\indexofcharacter ~
+\the\indexofcharacter \a
+\the\indexofcharacter \q
+\stoptyping
+
+In both cases active characters and unknown single character control sequences
+are valid. In addition this also works:
+
+\starttyping
+\chardef \foo 128
+\mathchardef\oof 130
+
+\the\indexofcharacter \foo
+\the\indexofcharacter \oof
+\stoptyping
+
+An important difference is that \prm {indexofcharacter} returns an integer and
+not a serialized number. A negative value indicates no valid character.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {indexofregister}}]
+
+You can use this instead of \prm {number} for determining the index of a register
+but it also returns a number when a register value is seen. The result is an
+integer, not a serialized number.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {inherited}}]
+
+When this prefix is used in a definition using \prm {let} the target will inherit
+all the properties of the source.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {initcatcodetable}}]
+
+This initializes the catcode table with the given index.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {initialpageskip}}]
+
+When a page starts the value of this register are used to initialize \prm
+{pagetotal}, \prm {pagestretch} and \prm {pageshrink}. This make nicer code than
+using a \prm {topskip} with weird values.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {initialtopskip}}]
+
+When set this one will be used instead of \prm {topskip}. The rationale is that
+the \prm {topskip} is often also used for side effects and compensation.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {input}}]
+
+There are several ways to use this primitive:
+
+\starttyping
+\input test
+\input {test}
+\input "test"
+\input 'test'
+\stoptyping
+
+When no suffix is given, \TEX\ will assume the suffix is \type {.tex}. The second
+one is normally used.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {inputlineno}}]
+
+This integer holds the current linenumber but it is not always reliable.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {insert}}]
+
+This stores content in the insert container with the given index. In \LUAMETATEX\
+inserts bubble up to outer boxes so we don't have the \quote {deeply buried
+insert issue}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {insertbox}}]
+
+This is the accessor for the box (with results) of an insert with the given
+index. This is equivalent to the \prm {box} in the traditional method.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertcopy}}]
+
+This is the accessor for the box (with results) of an insert with the given
+index. It makes a copy so the original is kept. This is equivalent to a \prm
+{copy} in the traditional method.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertdepth}}]
+
+This is the (current) depth of the inserted material with the given index. It is
+comparable to the \prm {dp} in the traditional method.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertdistance}}]
+
+This is the space before the inserted material with the given index. This is
+equivalent to \prm {glue} in the traditional method.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertheight}}]
+
+This is the (current) depth of the inserted material with the given index. It is
+comparable to the \prm {ht} in the traditional method.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertheights}}]
+
+This is the combined height of the inserted material.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertlimit}}]
+
+This is the maximum height that the inserted material with the given index can
+get. This is equivalent to \prm {dimen} in the traditional method.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertmaxdepth}}]
+
+This is the maximum depth that the inserted material with the given index can
+get.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertmode}}]
+
+In traditional \TEX\ inserts are controlled by a \prm {box}, \prm {dimen}, \prm
+{glue} and \prm {count} register with the same index. The allocators have to take
+this into account. When this primitive is set to one a different model is
+followed with its own namespace. There are more abstract accessors to interface
+to this. \footnote {The old model might be removed at some point.}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertmultiplier}}]
+
+This is the height (contribution) multiplier for the inserted material with the
+given index. This is equivalent to \prm {count} in the traditional method.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {insertpenalties}}]
+
+This dual purpose internal counter holds the sum of penalties for insertions that
+got split. When we're the output routine in reports the number of insertions that
+is kept in store.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {insertpenalty}}]
+
+This is the insert penalty associated with the inserted material with the given
+index.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertprogress}}]
+
+This returns the current accumulated insert height of the insert with the given
+index.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertstorage}}]
+
+The value passed will enable (one) or disable (zero) the insert with the given
+index.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertstoring}}]
+
+The value passed will enable (one) or disable (zero) inserts.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertunbox}}]
+
+This is the accessor for the box (with results) of an insert with the given
+index. It makes a copy so the original is kept. The content is unpacked and
+injected. This is equivalent to an \prm {unvbox} in the traditional method.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertuncopy}}]
+
+This is the accessor for the box (with results) of an insert with the given
+index. It makes a copy so the original is kept. The content is unpacked and
+injected. This is equivalent to the \prm {unvcopy} in the traditional method.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {insertwidth}}]
+
+This is the (current) width of the inserted material with the given index. It is
+comparable to the \prm {wd} in the traditional method.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {instance}}]
+
+This prefix flags a macro as an instance which is mostly relevant when a macro
+package want to categorize macros.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {integerdef}}]
+
+You can alias to a count (integer) register with \prm {countdef}:
+
+\starttyping
+\countdef\MyCount134
+\stoptyping
+
+Afterwards the next two are equivalent:
+
+\starttyping
+\MyCount = 99
+\count1234 = 99
+\stoptyping
+
+where \type {\MyCount} can be a bit more efficient because no index needs to be
+scanned. However, in terms of storage the value (here 99) is always in the register
+so \type {\MyCount} has to get there. This indirectness has the benefit that directly
+setting the value is reflected in the indirect accessor.
+
+\starttyping
+\integerdef\MyCount = 99
+\stoptyping
+
+This primitive also defines a numeric equivalent but this time the number is stored
+with the equivalent. This means that:
+
+\starttyping
+\let\MyCopyOfCount = \MyCount
+\stoptyping
+
+will store the {\em current} value of \type {\MyCount} in \type {\MyCopyOfCount} and
+changing either of them is not reflected in the other.
+
+The usual \prm {advance}, \prm {multiply} and \prm {divide} can be used with these
+integers and they behave like any number. But compared to registers they are actually
+more a constant.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {interactionmode}}]
+
+This internal integer can be used to set or query the current interaction mode:
+
+\starttabulate[||||]
+\NC \type {\batchmode } \NC \the\batchmodecode \NC omits all stops and terminal output \NC \NR
+\NC \type {\nonstopmode } \NC \the\nonstopmodecode \NC omits all stops \NC \NR
+\NC \type {\scrollmode } \NC \the\scrollmodecode \NC omits error stops \NC \NR
+\NC \type {\errorstopmode} \NC \the\errorstopmodecode \NC stops at every opportunity to interact \NC \NR
+\stoptabulate
+
+% In \LUAMETATEX, for consistency, we have enabled these four as integers after
+% \prm {the} but we can also decide to remove them and do this. So we leave this
+% as an undocumented feature. It could have been an \ETEX\ way of abstracting the
+% numeric values.
+%
+% \untraced\permanent\protected\def\batchmode {\interactionmode\batchmodecode}
+% \untraced\permanent\protected\def\nonstopmode {\interactionmode\nonstopmodecode}
+% \untraced\permanent\protected\def\scrollmode {\interactionmode\scrollmodecode}
+% \untraced\permanent\protected\def\errorstopmode{\interactionmode\errorstopmodecode}
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {interlinepenalties}}]
+
+This is a more granular variant of \prm {interlinepenalty}: an array of penalties
+to be put between successive line from the start of a paragraph. The list starts
+with the number of penalties that gets passed.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {interlinepenalty}}]
+
+This is the penalty that is put between lines.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {jobname}}]
+
+This gives the current job name without suffix: {\tttf \jobname}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {kern}}]
+
+A kern is injected with the given dimension. For variants that switch to a mode
+we have \prm {hkern} and \prm {vkern}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {language}}]
+
+Sets (or returns) the current language, a number. In \LUATEX\ and \LUAMETATEX\
+the current language is stored in the glyph nodes.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {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} \par
+
+\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} \par
+\stopbuffer
+
+\typebuffer
+
+The value of \prm {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
+\prm {everypar} is expanded which in turn can involve macros. You can see that
+in the second block (that is: unless we changed \prm {everypar} in the
+meantime).
+
+{\getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {lastatomclass}}]
+
+This returns the class number of the last atom seen in the math input parser.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {lastboundary}}]
+
+This primitive looks back in the list for a user boundary injected with \prm
+{boundary} and when seen it returns that value or otherwise zero.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {lastbox}}]
+
+When issued this primitive will, if possible, pull the last box from the current
+list.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {lastchkdimension}}]
+
+When the last check for a dimension with \prm {ifchkdimension} was successful
+this primitive returns the value.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {lastchknumber}}]
+
+When the last check for an integer with \prm {ifchknumber} was successful this
+primitive returns the value.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {lastkern}}]
+
+This returns the last kern seen in the list (if possible).
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {lastleftclass}}]
+
+This variable registers the first applied math class in a formula.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {lastlinefit}}]
+
+The \ETEX\ manuals explains this parameter in detail but in practice it is enough
+to know that when set to 1000 spaces in the last line might match those in the
+previous line. Basically it counters the strong push of a \prm {parfillskip}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {lastloopiterator}}]
+
+In addition to \prm {currentloopiterator} we have a variant that stores the value
+in case an unexpanded loop is used:
+
+\startbuffer
+\localcontrolledrepeat 8 { [\the\currentloopiterator\eq\the\lastloopiterator] }
+\expandedrepeat 8 { [\the\currentloopiterator\eq\the\lastloopiterator] }
+\unexpandedrepeat 8 { [\the\currentloopiterator\ne\the\lastloopiterator] }
+\stopbuffer
+
+\typebuffer
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {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={\prm {lastnodesubtype}}]
+
+When possible this returns the subtype of the last node in the current node list.
+Possible values can be queried (for each node type) via \LUA\ helpers.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {lastnodetype}}]
+
+When possible this returns the type of the last node in the current node list.
+Possible values can be queried via \LUA\ helpers.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {lastpageextra}}]
+
+This reports the last applied (permitted) overshoot.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {lastparcontext}}]
+
+When a paragraph is wrapped up the reason is reported by this state variable.
+Possible values are:
+
+\startcolumns[n=4]
+\getbuffer[engine:syntax:parcontextcodes]
+\stopcolumns
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {lastpartrigger}}]
+
+There are several reasons for entering a paragraphs and some are automatic and
+triggered by other commands that force \TEX\ into horizontal mode.
+
+\startcolumns[n=4]
+\getbuffer[engine:syntax:partriggercodes]
+\stopcolumns
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {lastpenalty}}]
+
+This returns the last penalty seen in the list (if possible).
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {lastrightclass}}]
+
+This variable registers the last applied math class in a formula.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {lastskip}}]
+
+This returns the last glue seen in the list (if possible).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {lccode}}]
+
+When the \prm {lowercase} operation is applied the lowercase code of a character
+is used for the replacement. This primitive is used to set that code, so it
+expects two character number. The code is also used to determine what characters
+make a word suitable for hyphenation, although in \LUATEX\ we introduced the \prm
+{hj} code for that.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {leaders}}]
+
+See \prm {gleaders} for an explanation.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {left}}]
+
+Inserts the given delimiter as left fence in a math formula.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {lefthyphenmin}}]
+
+This is the minimum number of characters after the last hyphen in a hyphenated
+word.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {leftmarginkern}}]
+
+The dimension returned is the protrusion kern that has been added (if at all)
+to the left of the content in the given box.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {leftskip}}]
+
+This skip will be inserted at the left of every line.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {leqno}}]
+
+This primitive stores the (typeset) content (presumably a number) and when the
+display formula is wrapped that number will end up left of the formula.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {let}}]
+
+Where a \prm {def} creates a new macro, either or not with argument, a \prm {let}
+creates an alias. You are not limited to aliasing macros, basically everything
+can be aliased.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {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}\par
+\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.
+
+{\tttf \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}\par
+\stopbuffer
+
+\typebuffer
+
+Of course \type {\bf} and \type {\it} are \CONTEXT\ specific commands:
+
+{\tttf \getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {letcsname}}]
+
+It is easy to see that we save two tokens when we use this primitive. As with the
+\type {..defcs..} variants it also saves a push back of the composed macro name.
+
+\starttyping
+\expandafter\let\csname MyMacro:1\endcsname\relax
+ \letcsname MyMacro:1\endcsname\relax
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {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={\prm {letmathatomrule}}]
+
+You can change the class for a specific style. This probably only makes sense
+for user classes. It's one of those features that we used when experimenting
+with more control.
+
+\starttyping
+\letmathatomrule 4 = 4 4 0 0
+\letmathatomrule 5 = 5 5 0 0
+\stoptyping
+
+This changes the classes~4 and~5 into class~ 0 in the two script styles and keeps
+them the same in display and text. We leave it to the reader to ponder how useful
+this is.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {letmathparent}}]
+
+This primitive takes five arguments: the target class, and four classes that
+determine the pre penalty class, post penalty class, options class and a dummy
+class for future use.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {letmathspacing}}]
+
+By default inter|-|class spacing inherits from the ordinary class but you can
+remap specific combinations is you want:
+
+\starttyping
+\letmathspacing \mathfunctioncode
+ \mathordinarycode \mathordinarycode
+ \mathordinarycode \mathordinarycode
+\stoptyping
+
+The first value is the target class, and the nest four tell how it behaves in
+display, text, script and script script style. Here \typ {\mathfunctioncode} is a
+\CONTEXT\ specific class (\the\mathfunctioncode), one of the many.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {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\par
+\stopbuffer
+
+\typebuffer
+
+The typeset meaning in this example is:
+
+{\tttf \getbuffer}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {lettolastnamedcs}}]
+
+The \prm {lastnamedcs} primitive is somewhat special as it is a (possible)
+reference to a control sequence which is why we have a dedicated variant of
+\prm {let}.
+
+\startbuffer
+\csname relax\endcsname\let \foo\lastnamedcs \meaning\foo
+\csname relax\endcsname\expandafter\let\expandafter \oof\lastnamedcs \meaning\oof
+\csname relax\endcsname\lettolastnamedcs \ofo \meaning\ofo
+\stopbuffer
+
+\typebuffer % we need oneliners because intermediate csnames kick in
+
+These give the following where the first one obviously is not doing what we want
+and the second one is kind of cumbersome.
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {lettonothing}}]
+
+This one let's a control sequence to nothing. Assuming that \type {\empty}
+is indeed empty, these two lines are equivalent.
+
+\starttyping
+\let \foo\empty
+\lettonothing\oof
+\stoptyping
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {limits}}]
+
+This is a modifier: it flags the previous math atom to have its scripts above and
+below the (summation, product, integral etc.) symbol. In \LUAMETATEX\ this can be
+any atom (that is: any class). In display mode the location defaults to above and
+below.
+
+Like any modifier it looks back for a math specific element. This means that the
+following will work well:
+
+\starttyping
+\sum \limits ^2 _3
+\sum ^2 \limits _3
+\sum ^2 _3 \limits
+\sum ^2 _3 \limits \nolimits \limits
+\stoptyping
+
+because scripts are bound to these elements so looking back just sees the element.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {linebreakcriterion}}]
+
+The par builder has a concept of \quote {compatible} lines, and has categories
+for that: loose, decent and tight. In \LUAMETATEX\ we also have semi|-|loose and
+semi|-|tight as intermediate categories. This parameter can set the ranges for
+those, using four double bytes:
+
+\starttabulate[|T|l|c|]
+\NC 0x7F000000 \NC semi tight \NC 12 \NC \NR
+\NC 0x007F0000 \NC decent \NC 12 \NC \NR
+\NC 0x00007F00 \NC semi loose \NC 12 \NC \NR
+\NC 0x0000007F \NC loose \NC 99 \NC \NR
+\stoptabulate
+
+The (decimal) default values are given in the last column. Don't expect a big
+influence from changing these and this option is mostly a side effect of
+experiments.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {linebreakoptional}}]
+
+This selects the optional text range that is to be used. Optional content is
+marked with {optionalboundary} nodes.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {linebreakpasses}}]
+
+When set to a positive value it will apply additional line break runs defined
+with \prm {parpasses} until the criteria set in there are met. When set to~$-1$
+it will signal a final pass
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {linedirection}}]
+
+This sets the text direction (1 for \type {r2l}) to the given value but keeps
+preceding glue into the range.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {linepenalty}}]
+
+Every line gets this penalty attached, so normally it is a small value, like
+here: \the \linepenalty.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {lineskip}}]
+
+This is the amount of glue that gets added when the distance between lines falls
+below \prm {lineskiplimit}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {lineskiplimit}}]
+
+When the distance between two lines becomes less than \prm {lineskiplimit} a \prm
+{lineskip} glue item is added.
+
+\startbuffer
+\ruledvbox{
+ \lineskiplimit 0pt \lineskip3pt \baselineskip0pt
+ \ruledhbox{line 1}
+ \ruledhbox{line 2}
+ \ruledhbox{\tx line 3}
+}
+\stopbuffer
+
+\typebuffer
+
+Normally the \prm {baselineskip} kicks in first but here we've set that to zero,
+so we get two times a 3pt glue injected.
+
+\startlocallinecorrection
+\getbuffer
+\stoplocallinecorrection
+
+\stopoldprimitive
+
+% \startnewprimitive[title={\prm {localbrokenpenalty}}]
+% \stopnewprimitive
+
+\startnewprimitive[title={\prm {localcontrol}}]
+
+This primitive takes a single token:
+
+\startbuffer
+\edef\testa{\scratchcounter123 \the\scratchcounter}
+\edef\testc{\testa \the\scratchcounter}
+\edef\testd{\localcontrol\testa \the\scratchcounter}
+\stopbuffer
+
+\typebuffer
+
+The three meanings are:
+
+\start \getbuffer
+\starttabulate[|T|T|]
+\NC \string\testa \NC \meaning\testa \NC \NR
+\NC \string\testc \NC \meaning\testc \NC \NR
+\NC \string\testd \NC \meaning\testd \NC \NR
+\stoptabulate
+\stop
+
+The \prm {localcontrol} makes that the following token gets expanded so we don't
+see the yet to be expanded assignment show up in the macro body.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {localcontrolled}}]
+
+The previously described local control feature comes with two extra helpers. The
+\prm {localcontrolled} primitive takes a token list and wraps this into a local
+control sidetrack. For example:
+
+\startbuffer
+\edef\testa{\scratchcounter123 \the\scratchcounter}
+\edef\testb{\localcontrolled{\scratchcounter123}\the\scratchcounter}
+\stopbuffer
+
+\typebuffer
+
+The two meanings are:
+
+\start \getbuffer
+\starttabulate[|T|T|]
+\NC \string\testa \NC \meaningfull\testa \NC \NR
+\NC \string\testb \NC \meaningfull\testb \NC \NR
+\stoptabulate
+\stop
+
+The assignment is applied immediately in the expanded definition.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {localcontrolledendless}}]
+
+As the name indicates this will loop forever. You need to explicitly quit the
+loop with \prm {quitloop} or \prm {quitloopnow}. The first quitter aborts the
+loop at the start of a next iteration, the second one tries to exit immediately,
+but is sensitive for interference with for instance nested conditionals.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {localcontrolledloop}}]
+
+As with more of the primitives discussed here, there is a manual in the \quote
+{lowlevel} subset that goes into more detail. So, here a simple example has to
+do:
+
+\startbuffer
+\localcontrolledloop 1 100 1 {%
+ \ifnum\currentloopiterator>6\relax
+ \quitloop
+ \else
+ [\number\currentloopnesting:\number\currentloopiterator]
+ \localcontrolledloop 1 8 1 {%
+ (\number\currentloopnesting:\number\currentloopiterator)
+ }\par
+ \fi
+}
+\stopbuffer
+
+\typebuffer
+
+Here we see the main loop primitive being used nested. The code shows how we can
+\prm {quitloop} and have access to the \prm {currentloopiterator} as well as the
+nesting depth \prm {currentloopnesting}.
+
+\startpacked \getbuffer \stoppacked
+
+Be aware of the fact that \prm {quitloop} will end the loop at the {\em next}
+iteration so any content after it will show up. Normally this one will be issued
+in a condition and we want to end that properly. Also keep in mind that because
+we use local control (a nested \TEX\ expansion loop) anything you feed back can
+be injected out of order.
+
+The three numbers can be separated by an equal sign which is a trick to avoid
+look ahead issues that can result from multiple serialized numbers without spaces
+that indicate the end of sequence of digits.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {localcontrolledrepeat}}]
+
+This one takes one instead three arguments which looks a bit better
+in simple looping.
+
+\stopnewprimitive
+
+% \startnewprimitive[title={\prm {localinterlinepenalty}}]
+% \stopnewprimitive
+
+\startnewprimitive[title={\prm {localleftbox}}]
+
+This sets the box that gets injected at the left of every line.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {localleftboxbox}}]
+
+This returns the box set with \prm {localleftbox}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {localmiddlebox}}]
+
+This sets the box that gets injected at the left of every line but its width
+is ignored.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {localmiddleboxbox}}]
+
+This returns the box set with \prm {localmiddlebox}.
+
+\stopnewprimitive
+
+% \startnewprimitive[title={\prm {localpretolerance}}]
+% \stopnewprimitive
+
+\startnewprimitive[title={\prm {localrightbox}}]
+
+This sets the box that gets injected at the right of every line.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {localrightboxbox}}]
+
+This returns the box set with \prm {localrightbox}.
+
+\stopnewprimitive
+
+% \startnewprimitive[title={\prm {localtolerance}}]
+% \stopnewprimitive
+
+\startoldprimitive[title={\prm {long}}][obsolete=yes]
+
+This original prefix gave the macro being defined the property that it could not
+have \prm {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={\prm {looseness}}]
+
+The number fo lines in the current paragraph will be increased by given number of
+lines. For this to succeed there need to be enough stretch in the spacing to make
+that happen. There is some wishful thinking involved.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {lower}}]
+
+This primitive takes two arguments, a dimension and a box. The box is moved down.
+The operation only succeeds in horizontal mode.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {lowercase}}]
+
+This token processor converts character tokens to their lowercase counterparts as
+defined per \prm {lccode}. In order to permit dirty tricks active characters are
+also processed. We don't really use this primitive in \CONTEXT, but for
+consistency we let it respond to \prm {expand}: \footnote {Instead of providing
+\type {\lowercased} and \type {\uppercased} primitives that would clash with
+macros anyway.}
+
+\startbuffer
+\edef \foo {\lowercase{tex TeX \TEX}} \meaningless\foo
+\lowercase{\edef\foo {tex TeX \TEX}} \meaningless\foo
+\edef \foo{\expand\lowercase{tex TeX \TEX}} \meaningless\foo
+\stopbuffer
+
+\typebuffer
+
+Watch how \prm {lowercase} is not expandable but can be forced to. Of course, as
+the logo macro is protected the \TEX\ logo remains mixed case.
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {lpcode}}]
+
+This one can be used to set the left protrusion factor of a glyph in a font and
+takes three arguments: font, character code and factor. It is kind of obsolete
+because we can set up vectors at definition time and tweaking from \TEX\ can have
+side effects because it globally adapts the font.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luabytecode}}]
+
+This behaves like \prm {luafunction} but here the number is a byte code register.
+These bytecodes are in the \typ {lua.bytecode} array.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luabytecodecall}}]
+
+This behaves like \prm {luafunctioncall} but here the number is a byte code
+register. These bytecodes are in the \typ {lua.bytecode} array.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luacopyinputnodes}}]
+
+When set to a positive value this will ensure that when nodes are printed from
+\LUA\ to \TEX\ copies are used.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luadef}}]
+
+% \edef\foocode{\ctxlua{
+% context(
+% context.functions.register(
+% function() context("!") end
+% )
+% )
+% }}
+
+This command relates a (user) command to a \LUA\ function registered in the \typ
+{lua.lualib_get_functions_table()}, so after:
+
+\starttyping
+\luadef\foo123
+\stoptyping
+
+the \type {\foo} command will trigger the function at index 123. Of course a
+macro package has to make sure that these definitions are unique. \footnote
+{Plain \TEX\ established a norm for allocating registers, like \typ {\newdimen}
+but there is no such convention for \LUA\ functions.}
+
+This command is accompanied by \prm {luafunctioncall} and
+\prm {luafunction}. When we have funciton 123 defined as
+
+\starttyping
+function() tex.sprint("!") end
+\stoptyping
+
+the following:
+
+\starttyping
+(\luafunctioncall \foocode ?)
+(\normalluafunction\foocode ?)
+(\foo ?)
+\stoptyping
+
+gives three times \type {(!?)}. But this:
+
+\starttyping
+\edef\oof{\foo } \meaning\oof % protected
+\edef\oof{\luafunctioncall \foocode} \meaning\oof % protected
+\edef\oof{\normalluafunction\foocode} \meaning\oof % expands
+\stoptyping
+
+returns:
+
+\starttyping
+macro:!
+macro:\luafunctioncall 1740
+macro:!
+\stoptyping
+
+Because the definition command is like any other
+
+\starttyping
+\permanent\protected\luadef\foo123
+\stoptyping
+
+boils down to:
+
+\starttyping
+permanent protected luacall 123
+\stoptyping
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luaescapestring}}]
+
+This command converts the given (token) list into something that is acceptable
+for \LUA. It is inherited from \LUATEX\ and not used in \CONTEXT.
+
+\startbuffer
+\directlua { tex.print ("\luaescapestring {{\tt This is a "test".}}") }
+\stopbuffer
+
+\typebuffer
+
+Results in: \inlinebuffer\space (Watch the grouping.)
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luafunction}}]
+
+The integer passed to this primitive is the index in the table returned by \typ
+{lua.lualib_get_functions_table()}. Of course a macro package has to provide
+reliable management for this. This is a so called convert command so it expands
+in an expansion context (like an \prm {edef}).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luafunctioncall}}]
+
+The integer passed to this primitive is the index in the table returned by \typ
+{lua.lualib_get_functions_table()}. Of course a macro package has to provide
+reliable management for this. This primitive doesn't expand in an expansion
+context (like an \prm {edef}).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luatexbanner}}]
+
+This gives: {\tttf \luatexbanner}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luatexrevision}}]
+
+This is an integer. The current value is: {\tttf \number\luatexrevision}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {luatexversion}}]
+
+This is an integer. The current value is: {\tttf \number\luatexversion}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mark}}][obsolete=yes]
+
+The given token list is stored in a node in the current list and might become
+content of \prm {topmark}, \prm {botmark} or \prm {firstmark} when a page split
+off, or in the case of a box split in \prm {splitbotmark} or \prm
+{splitfirstmark}. In \LUAMETATEX\ deeply burried marks bubbly up to an outer box
+level.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {marks}}]
+
+This command is similar to \prm {mark} but first expects a number of a mark
+register. Multiple marks were introduced in \ETEX.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {mathaccent}}][obsolete=yes]
+
+This takes a number and a math object to put the accent on. The four byte number
+has a dummy class byte, a family byte and two index bytes. It is replaced by \prm
+{Umathaccent} that handles wide fonts.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathatom}}]
+
+This operation wraps following content in a atom with the given class. It is part
+of \LUAMETATEX's extended math support. There are three class related
+key|/|values: \type {class}, \typ {leftclass} and \typ {rightclass} (or \type
+{all} for all of them). When none is given this command expects a class number
+before scanning the content. The \type {options} key expects a bitset but there
+are also direct option keys, like \type {limits}, \typ {nolimits}, \type
+{unpack}, \type {unroll}, \type {single}, \type {nooverflow}, \type {void} and
+\type {phantom}. A \type {source} id can be set, one or more \type {attr}
+assigned, and for specific purposes \typ {textfont} and \typ {mathfont}
+directives are accepted. Features like this are discussed in dedicated manuals.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathatomglue}}]
+
+This returns the glue that will be inserted between two atoms of a given class
+for a specific style.
+
+\startbuffer
+\the\mathatomglue \textstyle 1 1
+\the\mathatomglue \textstyle 0 2
+\the\mathatomglue \scriptstyle 1 1
+\the\mathatomglue \scriptstyle 0 2
+\stopbuffer
+
+\typebuffer
+
+\startlines \tttf
+\getbuffer
+\stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathatomskip}}]
+
+\startbuffer
+$x x$
+$x \mathatomskip \textstyle 1 1 x$
+$x \mathatomskip \textstyle 0 2 x$
+$x \mathatomskip \scriptstyle 1 1 x$
+$x \mathatomskip \scriptstyle 0 2 x$
+\stopbuffer
+
+This injects a glue with the given style and class pair specification:
+\inlinebuffer.
+
+\typebuffer
+
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathbackwardpenalties}}]
+
+See \prm {mathforwardpenalties} for an explanation.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathbeginclass}}]
+
+This variable can be set to signal the class that starts the formula (think of an
+imaginary leading atom).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mathbin}}]
+
+This operation wraps following content in a atom with class \quote {binary}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathboundary}}]
+
+This primitive is part of an experiment with granular penalties in math. When set
+nested fences will use the \prm {mathdisplaypenaltyfactor} or \prm
+{mathinlinepenaltyfactor} to increase nested penalties. A bit more control is
+possible with \prm {mathboundary}:
+
+\starttabulate[||||]
+\NC 0 \NC begin \NC factor 1000 \NC \NR
+\NC 1 \NC end \NC factor 1000 \NC \NR
+\NC 2 \NC begin \NC given factor \NC \NR
+\NC 3 \NC end \NC given factor \NC \NR
+\stoptabulate
+
+These will be used when the mentioned factors are zero.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mathchar}}][obsolete=yes]
+
+Replaced by \prm {Umathchar} this old one takes a four byte number: one byte for
+the class, one for the family an two for the index. The specified character is
+appended to to the list.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathcharclass}}]
+
+Returns the slot (in the font) of the given math character.
+
+\startbuffer
+\the\mathcharclass\Umathchar 4 2 123
+\stopbuffer
+
+\typebuffer
+
+The first passed number is the class, so we get: \inlinebuffer.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mathchardef}}][obsolete=yes]
+
+Replaced by \prm {Umathchardef} this primitive relates a control sequence with a
+four byte number: one byte for the class, one for the family an two for the
+index. The defined command will insert that character.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathcharfam}}]
+
+Returns the family number of the given math character.
+
+\startbuffer
+\the\mathcharfam\Umathchar 4 2 123
+\stopbuffer
+
+\typebuffer
+
+The second passed number is the family, so we get: \inlinebuffer.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathcharslot}}]
+
+Returns the slot (or index in the font) of the given math character.
+
+\startbuffer
+\the\mathcharslot\Umathchar 4 2 123
+\stopbuffer
+
+\typebuffer
+
+The third passed number is the slot, so we get: \inlinebuffer.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathcheckfencesmode}}]
+
+When set to a positive value there will be no warning if a right fence (\prm
+{right} or \prm {Uright}) is missing.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mathchoice}}]
+
+This command expects four subformulas, for display, text, script and scriptscript
+and it will eventually use one of them depending on circumstances later on. Keep
+in mind that a formula is first scanned and when that is finished the analysis
+and typesetting happens.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathclass}}]
+
+There are build in classes and user classes. The first possible user class is
+\cldcontext {tex . magicconstants . mathfirstuserclass} and the last one is
+\cldcontext {tex . magicconstants . mathlastuserclass}. You can better not touch
+the special classes \quote {all} (\number \mathallcode), \quote {begin} (\number
+\mathbegincode) and \quote {end} (\number \mathendcode). The basic 8 classes that
+original \TEX\ provides are of course also present in \LUAMETATEX. In addition we
+have some that relate to constructs that the engine builds.
+
+\starttabulate[|l|l|T|l|]
+\FL
+\NC ordinary \NC ord \NC \the\mathordinarycode \NC the default \NR
+\NC operator \NC op \NC \the\mathoperatorcode \NC small and large operators \NC \NR
+\NC binary \NC bin \NC \the\mathbinarycode \NC \NC \NR
+\NC relation \NC rel \NC \the\mathrelationcode \NC \NC \NR
+\NC open \NC \NC \the\mathopencode \NC \NC \NR
+\NC close \NC \NC \the\mathclosecode \NC \NC \NR
+\NC punctuation \NC punct \NC \the\mathpunctuationcode \NC \NC \NR
+\NC variable \NC \NC \the\mathvariablecode \NC adapts to the current family \NC \NR
+\NC active \NC \NC \the\mathactivecode \NC character marked as such becomes active \NR
+\NC inner \NC \NC \the\mathinnercode \NC this class is not possible for characters \NR
+\ML
+\NC under \NC \NC \the\mathundercode \NC \NC \NR
+\NC over \NC \NC \the\mathovercode \NC \NC \NR
+\NC fraction \NC \NC \the\mathfractioncode \NC \NC \NR
+\NC radical \NC \NC \the\mathradicalcode \NC \NC \NR
+\NC middle \NC \NC \the\mathmiddlecode \NC \NC \NR
+\NC accent \NC \NC \the\mathaccentcode \NC \NC \NR
+\NC fenced \NC \NC \the\mathfencedcode \NC \NC \NR
+\NC ghost \NC \NC \the\mathghostcode \NC \NC \NR
+\NC vcenter \NC \NC \the\mathvcentercode \NC \NC \NR
+\LL
+\stoptabulate
+
+There is no standard for user classes but \CONTEXT\ users should be aware of
+quite some additional ones that are set up. The engine initialized the default
+properties of classes (spacing, penalties, etc.) the same as original \TEX.
+
+Normally characters have class bound to them but you can (temporarily) overload
+that one. The \prm {mathclass} primitive expects a class number and a valid
+character number or math character and inserts the symbol as if it were of the
+given class; so the original class is replaced.
+
+\startbuffer
+\ruledhbox{$(x)$} and \ruledhbox{$\mathclass 1 `(x\mathclass 1 `)$}
+\stopbuffer
+
+\typebuffer
+
+Changing the class is likely to change the spacing, compare \inlinebuffer.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mathclose}}]
+
+This operation wraps following content in a atom with class \quote {close}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {mathcode}}][obsolete=yes]
+
+This maps a character to one in a family: the assigned value has one byte for the
+class, one for the family and two for the index. It has little use in an
+\OPENTYPE\ math setup.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathdictgroup}}]
+
+This is an experimental feature that in due time will be explored in \CONTEXT. It
+currently has no consequences for rendering.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathdictionary}}]
+
+This is an experimental feature that in due time will be explored in \CONTEXT. It
+currently has no consequences for rendering.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathdictproperties}}]
+
+This is an experimental feature that in due time will be explored in \CONTEXT. It
+currently has no consequences for rendering.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathdirection}}]
+
+When set to 1 this will result in \type {r2l} typeset math formulas but of course
+you then also need to set up math accordingly (which is the case in \CONTEXT).
+
+\stopnewprimitive
+
+% \startnewprimitive[title={\prm {mathdiscretionary}}]
+% \stopnewprimitive
+
+\startnewprimitive[title={\prm {mathdisplaymode}}]
+
+Display mode is entered with two dollars (other characters can be used but the
+dollars are a convention). Mid paragraph display formulas get a different
+treatment with respect to the width and indentation than stand alone. When \prm
+{mathdisplaymode} is larger than zero the double dollars (or equivalents) will
+behave as inline formulas starting out in \prm {displaystyle} and with \prm
+{everydisplay} expanded.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathdisplaypenaltyfactor}}]
+
+This one is simular to \prm {mathinlinepenaltyfactor} but is used when we're in
+display style.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathdisplayskipmode}}]
+
+A display formula is preceded and followed by vertical glue specified by
+\prm{abovedisplayskip} and \prm {belowdisplayskip} or \prm
+{abovedisplayshortskip} and \prm {belowdisplayshortskip}. Spacing \quote {above}
+is always inserted, even when zero, but the spacing \quote {below} is only
+inserted when it is non|-|zero. There's also \prm {baselineskip} involved. The
+way spacing is handled can be influenced with \prm {mathdisplayskipmode}, which
+takes the following values:
+
+\starttabulate[|c|l|]
+\NC 0 \NC does the same as any \TEX\ engine \NC \NR
+\NC 1 \NC idem \NC \NR
+\NC 2 \NC only insert spacing when it is not zero \NC \NR
+\NC 3 \NC never insert spacing \NC \NR
+\stoptabulate
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathdoublescriptmode}}]
+
+When this parameter has a negative value double scripts trigger an error, so with
+\prm {superscript}, \prm {nosuperscript}, \prm {shiftedsuperscript}, \prm
+{superprescript}, \prm {nosuperprescript}, \prm {shiftedsuperprescript}, \prm
+{subscript}, \prm {nosubscript}, \prm {shiftedsubscript}, \prm {subprescript},
+\prm {nosubprescript}, \prm {shiftedsubprescript} and \prm {primescript}, as well
+as their (multiple) \type {_} and \type {^} aliases.
+
+A value of zero does the normal and inserts a dummy atom (basically a \type {{}})
+but a positive value is more interesting. Compare these:
+
+\startbuffer
+{\mathdoublescriptmode 0 $x_x_x$}
+{\mathdoublescriptmode"000000 $x_x_x$}
+{\mathdoublescriptmode"030303 $x_x_x$}
+{$x_x_x$}
+\stopbuffer
+
+\typebuffer
+
+The three pairs of bytes indicate the main class, left side class and right side
+class of the inserted atom, so we get this: \inlinebuffer. The last line gives
+what \CONTEXT\ is configured for.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathendclass}}]
+
+This variable can be set to signal the class that ends the formula (think of an
+imaginary trailing atom).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {matheqnogapstep}}]
+
+The display formula number placement heuristic puts the number on the same line
+when there is place and then separates it by a quad. In \LUATEX\ we decided to
+keep that quantity as it can be tight into the math font metrics but introduce
+a multiplier \prm {matheqnogapstep} that defaults to 1000.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathfontcontrol}}]
+
+This bitset controls how the math engine deals with fonts, and provides a way
+around dealing with inconsistencies in the way they are set up. The \prm
+{fontmathcontrol} makes it possible to bind options ot a specific math font. In
+practice, we just set up the general approach which ii possible because we
+normalize the math fonts and \quote {fix} issues at runtime.
+
+\getbuffer[engine:syntax:mathcontrolcodes]
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathforwardpenalties}}]
+
+Inline math can have multiple atoms and constructs and one can configure the
+penalties between then bases on classes. In addition it is possible to configure
+additional penalties starting from the beginning or end using \prm
+{mathforwardpenalties} and \prm {mathbackwardpenalties}. This is one the features
+that we added in the perspective of breaking paragraphs heavy on math into lines.
+It not that easy to come up with useable values.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathgluemode}}]
+
+We can influence the way math glue is handled. By default stretch and shrink is applied but
+this variable can be used to change that. The limit option ensures that the stretch and shrink
+doesn't go beyond their natural values.
+
+\getbuffer[engine:syntax:mathgluecodes]
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathgroupingmode}}]
+
+Normally a \type {{}} or \type {\bgroup}|-|\type {\egroup} pair in math create a
+math list. However, users are accustomed to using it also for grouping and then a
+list being created might not be what a user wants. As an alternative to the more
+verbose \prm {begingroup}|-|\prm {endgroup} or even less sensitive \prm
+{beginmathgroup}|-|\prm {endmathgroup} you can set the math grouping mode to a
+non zero value which makes curly braces (and the aliases) behave as expected.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathinlinepenaltyfactor}}]
+
+A math formula can have nested (sub)formulas and one might want to discourage a
+line break inside those. If this value is non zero it becomes a mulitiplier, so a
+value of 1000 will make an inter class penalty of 100 into 200 when at nesting
+level 2 and 500 when at level 5.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mathinner}}]
+
+This operation wraps following content in a atom with class \quote {inner}. In
+\LUAMETATEX\ we have more classes and this general wrapper one is therefore kind
+of redundant.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathleftclass}}]
+
+When set this class will be used when a formula starts.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathlimitsmode}}]
+
+When this parameter is set to a value larger than zero real dimensions are used
+and longer limits will not stick out, which is a traditional \TEX\ feature. We
+could have more advanced control but this will do.
+
+\startbuffer
+\dontleavehmode
+\ruledhbox{\dm{\left|\integral^{!!!!!!!!!!!}\right|}}
+\ruledhbox{\dm{\left|\integral^{!!!!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral^{!!!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral^{!!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral^{!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral^{!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral^{!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral^{!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral^{!!!} \right|}}
+\ruledhbox{\dm{\left|\integral^{!!} \right|}}
+\ruledhbox{\dm{\left|\integral^{!} \right|}}
+\blank
+\dontleavehmode
+\ruledhbox{\dm{\left|\integral_{!!!!!!!!!!!}\right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!} \right|}}
+\blank
+\dontleavehmode
+\ruledhbox{\dm{\left|\integral_{!} ^{!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!!!!}^{!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!} ^{!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!} ^{!!!!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!!!!}^{!!!!!!!!!} \right|}}
+\ruledhbox{\dm{\left|\integral_{!!!!!!!}^{!!!!!!!!!!!!!!!}\right|}}
+\ruledhbox{\dm{\left|\integral^{\mtext{for demanding}}_{\mtext{integral freaks}}\right|}}
+\stopbuffer
+
+Compare the zero setting:
+
+{\switchtobodyfont[modern]\setupmathoperators[integral][method=limits]\mathlimitsmode 0 \getbuffer}
+
+with the positive variant:
+
+{\switchtobodyfont[modern]\setupmathoperators[integral][method=limits]\mathlimitsmode 1 \getbuffer}
+
+Here we switched to Latin Modern because it's font dependent how serious this
+issue is. In Pagella all is fine in both modes.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathmainstyle}}]
+
+This inspector returns the outermost math style (contrary to \prm {mathstyle}),
+as we can see in the next examples where use these snippets:
+
+\startbuffer
+\def\foo{(\the\mathmainstyle,\the\mathstyle)}
+\def\oof{\sqrt[\foo]{\foo}}
+\def\ofo{\frac{\foo}{\foo}}
+\def\fof{\mathchoice{\foo}{\foo}{\foo}{\foo}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+When we use the regular math triggers we get this:
+
+\startbuffer
+$\displaystyle \foo + \oof + \ofo$
+$\textstyle \foo + \oof + \ofo$
+$\displaystyle \foo + \fof$
+$\textstyle \foo + \fof$
+$\scriptstyle \foo + \fof$
+$\scriptscriptstyle\foo + \fof$
+\stopbuffer
+
+\typebuffer
+
+\startlines
+\getbuffer
+\stoplines
+
+But we can also do this:
+
+\startbuffer
+\Ustartmathmode \displaystyle \foo + \oof + \ofo \Ustopmathmode
+\Ustartmathmode \textstyle \foo + \oof + \ofo \Ustopmathmode
+\Ustartmathmode \displaystyle \foo + \fof \Ustopmathmode
+\Ustartmathmode \textstyle \foo + \fof \Ustopmathmode
+\Ustartmathmode \scriptstyle \foo + \fof \Ustopmathmode
+\Ustartmathmode \scriptscriptstyle\foo + \fof \Ustopmathmode
+\stopbuffer
+
+\typebuffer
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathnolimitsmode}}]
+
+This parameter influences the placement of scripts after an operator. The reason
+we have this lays in the fact that traditional \TEX\ uses italic correction and
+\OPENTYPE\ math does the same but fonts are not consistent in how they set this
+up. Actually, in \OPENTYPE\ math it's the only reason that there is italic
+correction. Say that we have a shift $\delta$ determined by the italic correction:
+
+\starttabulate[|c|c|c|]
+\BC mode \BC top \BC bottom \NC \NR
+\NC $0$ \NC $0$ \NC $-\delta$ \NC \NR
+\NC $1$ \NC $\delta\times f_t$ \NC $\delta\times f_b$ \NC \NR
+\NC $2$ \NC $0$ \NC $0$ \NC \NR
+\NC $3$ \NC $0$ \NC $-\delta/2$ \NC \NR
+\NC $4$ \NC $\delta/2$ \NC $-\delta/2$ \NC \NR
+\NC $>15$ \NC $0$ \NC $-n\times\delta/1000$ \NC \NR
+\stoptabulate
+
+Mode~1 uses two font parameters: $f_b$: \prm {Umathnolimitsubfactor} and $f_t$:
+\prm {Umathnolimitsupfactor}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mathop}}]
+
+This operation wraps following content in a atom with class \quote {operator}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {mathopen}}]
+
+This operation wraps following content in a atom with class \quote {open}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {mathord}}]
+
+This operation wraps following content in a atom with class \quote {ordinary}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathparentstyle}}]
+
+This inspector returns the math style used in a construct, so is is either
+equivalent to \prm {mathmainstyle} or a nested \prm {mathstyle}. For instance
+in a nested fraction we get this (in \CONTEXT) in display formulas:
+
+\def\foo{(\the\mathmainstyle,\the\mathparentstyle,\the\mathstyle)}
+
+\dm{
+ \frac{\frac{\foo}{\foo}}{\frac{\foo}{\foo}} + \foo
+}
+
+but this in inline formulas:
+
+\im{
+ \frac{\frac{\foo}{\foo}}{\frac{\foo}{\foo}} + \foo
+}
+
+where the first element in a nested fraction.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathpenaltiesmode}}]
+
+Normally the \TEX\ math engine only inserts penalties when in textstyle. You can
+force penalties in displaystyle with this parameter. In inline math we always
+honor penalties, with mode~0 and mode~1 we get this:
+
+\pushoverloadmode
+
+\startlines
+{\mathpenaltiesmode=0 \let\mathpenaltiesmode\scratchcounter $\showmakeup[hpenalty]x+2x=0$}
+{\mathpenaltiesmode=1 \let\mathpenaltiesmode\scratchcounter $\showmakeup[hpenalty]x+2x=1$}
+\stoplines
+
+However in \CONTEXT, where all is done in inline math mode, we set this this
+parameter to~1, otherwise we wouldn't get these penalties, as shown next:
+
+{\mathpenaltiesmode=0 \let\mathpenaltiesmode\scratchcounter \startformula \showmakeup[hpenalty]x+2x=0 \stopformula}
+{\mathpenaltiesmode=1 \let\mathpenaltiesmode\scratchcounter \startformula \showmakeup[hpenalty]x+2x=1 \stopformula}
+
+\popoverloadmode
+
+If one uses a callback it is possible to force penalties from there too.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathpretolerance}}]
+
+This is used instead of \prm {pretolerance} when a breakpoint is calculated when
+a math formula starts.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mathpunct}}]
+
+This operation wraps following content in a atom with class \quote {punctuation}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {mathrel}}]
+
+This operation wraps following content in a atom with class \quote {relation}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathrightclass}}]
+
+When set this class will be used when a formula ends.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathrulesfam}}]
+
+When set, this family will be used for setting rule properties in fractions,
+under and over.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathrulesmode}}]
+
+When set to a non zero value rules (as in fractions and radicals) will be based
+on the font parameters in the current family.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathscale}}]
+
+In \LUAMETATEX\ we can either have a family of three (text, script and
+scriptscript) fonts or we can use one font that we scale and where we also pass
+information about alternative shapes for the smaller sizes. When we use this
+more compact mode this primitive reflects the scale factor used.
+
+\startbuffer
+\im {
+ \textstyle \the\mathscale\textfont \fam\enspace
+ \scriptstyle \the\mathscale\scriptfont \fam\enspace
+ \scriptscriptstyle\the\mathscale\scriptscriptfont\fam\enspace
+ \textstyle \the\mathscale\textfont \fam\enspace
+ \scriptstyle \the\mathscale\textfont \fam\enspace
+ \scriptscriptstyle\the\mathscale\textfont \fam
+
+}
+\stopbuffer
+
+What gets reported depends on how math is implemented, where in \CONTEXT\ we can
+have either normal or compact mode: \inlinebuffer. In compact mode we have the
+same font three times so then it doesn't matter which of the three is passed.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathscriptsmode}}]
+
+There are situations where you don't want \TEX\ to be clever and optimize the
+position of super- and subscripts by shifting. This parameter can be used to
+influence this.
+
+\startlinecorrection
+\startcombination[3*2]
+ {\startoverlay
+ {\ruledhbox {\mathscriptsmode 0 0: $x^2_2 + y^x_x + z_2 + w^2$}}
+ {\ruledhbox{\red \mathscriptsmode 1 1: $x^2_2 + y^x_x + z_2 + w^2$}}
+ \stopoverlay} {}
+ {\startoverlay
+ {\ruledhbox {\mathscriptsmode 0 0: $x^2_2 + y^x_x + z_2 + w^2$}}
+ {\ruledhbox{\red \mathscriptsmode 2 2: $x^2_2 + y^x_x + z_2 + w^2$}}
+ \stopoverlay} {}
+ {\startoverlay
+ {\ruledhbox {\mathscriptsmode 1 1: $x^2_2 + y^x_x + z_2 + w^2$}}
+ {\ruledhbox{\red \mathscriptsmode 2 2: $x^2_2 + y^x_x + z_2 + w^2$}}
+ \stopoverlay} {}
+ {\startoverlay
+ {\ruledhbox {\mathscriptsmode 0 0: $x^f_f + y^x_x + z_f + w^f$}}
+ {\ruledhbox{\red \mathscriptsmode 1 1: $x^f_f + y^x_x + z_f + w^f$}}
+ \stopoverlay} {1 over 0}
+ {\startoverlay
+ {\ruledhbox {\mathscriptsmode 0 0: $x^f_f + y^x_x + z_f + w^f$}}
+ {\ruledhbox{\red \mathscriptsmode 2 2: $x^f_f + y^x_x + z_f + w^f$}}
+ \stopoverlay} {2 over 0}
+ {\startoverlay
+ {\ruledhbox {\mathscriptsmode 1 1: $x^f_f + y^x_x + z_f + w^f$}}
+ {\ruledhbox{\red \mathscriptsmode 2 2: $x^f_f + y^x_x + z_f + w^f$}}
+ \stopoverlay} {2 over 1}
+\stopcombination
+\stoplinecorrection
+
+The next table shows what parameters kick in when:
+
+\starttabulate[|l|l|l|p|]
+\NC \BC or (1) \BC and (2) \BC otherwise \NC \NR
+\BC super \NC sup shift up \NC sup shift up \NC sup shift up,
+ sup bot min \NC \NR
+\BC sub \NC sub shift down \NC sub sup shift down \NC sub shift down,
+ sub top max \NC \NR
+\BC both \NC sub shift down \NC sub sup shift down \NC sub sup shift down,
+ sub sup vgap,
+ sup sub bot max \NC \NR
+\stoptabulate
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathslackmode}}]
+
+When positive this parameter will make sure that script spacing is discarded when
+there is no reason to add it.
+
+\startlinecorrection
+\startcombination[nx=3,ny=1]
+ {\mathslackmode0
+ \ruledhbox{$\setmscale{3}x^2 + x^2$}\space
+ \ruledhbox{$\setmscale{3}x^2$}}
+ {disabled (0)}
+ {\mathslackmode1
+ \ruledhbox{$\setmscale{3}x^2 + x^2$}\space
+ \ruledhbox{$\setmscale{3}x^2$}}
+ {enabled (1)}
+ {\startoverlay
+ {\mathslackmode0 \ruledhbox{$\setmscale{3}x^2 + x^2$}}
+ {\mathslackmode1 \red\ruledhbox{$\setmscale{3}x^2 + x^2$}}
+ \stopoverlay
+ \space
+ \startoverlay
+ {\mathslackmode0 \ruledhbox{$\setmscale{3}x^2$}}
+ {\mathslackmode1 \red\ruledhbox{$\setmscale{3}x^2$}}
+ \stopoverlay}
+ {{\red enabled} over disabled}
+\stopcombination
+\stoplinecorrection
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathspacingmode}}]
+
+Zero inter|-|class glue is not injected but setting this parameter to a positive
+value bypasses that check. This can be handy when checking (tracing) how (and
+what) spacing is applied. Keep in mind that glue in math is special in the sense
+that it is not a valid breakpoint. Line breaks in (inline) math are driven by
+penalties.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathstack}}]
+
+There are a few commands in \TEX\ that can behave confusing due to the way they
+are scanned. Compare these:
+
+\starttyping
+$ 1 \over 2 $
+$ 1 + x \over 2 + x$
+$ {1 + x} \over {2 + x}$
+$ {{1 + x} \over {2 + x}}$
+\stoptyping
+
+A single $1$ is an atom as is the curly braced ${1 + x}$. The two arguments to
+\prm {over} eventually will get typeset in the style that this fraction
+constructor uses for the numerator and denominator but on might actually also
+like to relate that to the circumstances. It is comparable to using a \prm
+{mathchoice}. In order not to waste runtime on four variants, which itself can have
+side effects, for instance when counters are involved, \LUATEX\ introduced
+\prm {mathstack}, used like:
+
+\starttyping
+$\mathstack {1 \over 2}$
+\stoptyping
+
+This \prm {mathstack} command will scan the next brace and opens a new math group
+with the correct (in this case numerator) math style. The \prm {mathstackstyle}
+primitive relates to this feature that defaults to \quote {smaller unless already
+scriptscript}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathstackstyle}}]
+
+This returns the (normally) numerator style but the engine can be configured to
+default to another style. Although all these in the original \TEX\ engines hard
+coded style values can be changed in \LUAMETATEX\ it is unlikely to happen. So
+this primitive will normally return the (current) style \quote {smaller unless
+already scriptscript}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathstyle}}]
+
+This returns the current math style, so \type {$\the \mathstyle$} gives $\the
+\mathstyle$.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathstylefontid}}]
+
+This returns the font id (a number) of a style|/|family combination. What you get
+back depends on how a macro package implements math fonts.
+
+\startbuffer
+(\the\mathstylefontid\textstyle \fam)
+(\the\mathstylefontid\scriptstyle \fam)
+(\the\mathstylefontid\scriptscriptstyle\fam)
+\stopbuffer
+
+\typebuffer
+
+In \CONTEXT\ gives: \inlinebuffer.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mathsurround}}]
+
+The kern injected before and after an inline math formula. In practice it will be
+set to zero, if only because otherwise nested math will also get that space
+added. We also have \prm {mathsurroundskip} which, when set, takes precedence.
+Spacing is controlled by \prm {mathsurroundmode}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mathsurroundmode}}]
+
+The possible ways to control spacing around inline math formulas in other manuals
+and mostly serve as playground.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathsurroundskip}}]
+
+When set this one wins over \prm {mathsurround}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {maththreshold}}]
+
+This is a glue parameter. The amount determines what happens: when it is non zero
+and the inline formula is less than that value it will become a special kind of
+box that can stretch and|/| or shrink within the given specification. The par
+builder will use these stretch and|/| or shrink components but it is up to one of
+the \LUA\ callbacks to deal with the content eventually (if at all). As this is
+somewhat specialized, more details can be found on \CONTEXT\ documentation.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {mathtolerance}}]
+
+This is used instead of \prm {tolerance} when a breakpoint is calculated when a
+math formula starts.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {maxdeadcycles}}]
+
+When the output routine is called this many times and no page is shipped out an
+error will be triggered. You therefore need to reset its companion counter \prm
+{deadcycles} if needed. Keep in mind that \LUAMETATEX\ has no real \prm {shipout}
+because providing a backend is up to the macro package.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {maxdepth}}]
+
+The depth of the page is limited to this value.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {meaning}}]
+
+We start with a primitive that will be used in the following sections. The
+reported meaning can look a bit different than the one reported by other engines
+which is a side effect of additional properties and more extensive argument
+parsing.
+
+\startbuffer
+\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaning\foo
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {meaningasis}}]
+
+Although it is not really round trip with the original due to information
+being lost this primitive tries to return an equivalent definition.
+
+\startbuffer
+\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningasis\foo
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {meaningful}}]
+
+This one reports a bit less than \prm {meaningful}.
+
+\startbuffer
+\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningful\foo
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {meaningfull}}]
+
+This one reports a bit more than \prm {meaning}.
+
+\startbuffer
+\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningfull\foo
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {meaningles}}]
+
+This one reports a bit less than \prm {meaningless}.
+
+\startbuffer
+\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningles\foo
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {meaningless}}]
+
+This one reports a bit less than \prm {meaning}.
+
+\startbuffer
+\tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningless\foo
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {medmuskip}}]
+
+A predefined mu skip register that can be used in math (inter atom) spacing. The
+current value is {\tt \the\medmuskip}. In traditional \TEX\ most inter atom
+spacing is hard coded using the predefined registers.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {message}}]
+
+Prints the serialization of the (tokenized) argument to the log file and|/|or
+console.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {middle}}]
+
+Inserts the given delimiter as middle fence in a math formula. In \LUAMETATEX\ it
+is a full blown fence and not (as in \ETEX) variation of \prm {open}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {mkern}}]
+
+This one injects a kern node in the current (math) list and expects a value in so
+called mu units.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {month}}]
+
+This internal number starts out with the month that the job started.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {moveleft}}]
+
+This primitive takes two arguments, a dimension and a box. The box is moved to
+the left. The operation only succeeds in vertical mode.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {moveright}}]
+
+This primitive takes two arguments, a dimension and a box. The box is moved to
+the right. The operation only succeeds in vertical mode.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {mskip}}]
+
+The given math glue (in \type {mu} units) is injected in the horizontal list. For
+this to succeed we need to be in math mode.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {muexpr}}]
+
+This is a companion of \prm {glueexpr} so it handles the optional stretch and
+shrink components. Here math units (\type {mu}) are expected.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mugluespecdef}}]
+
+A variant of \prm {gluespecdef} that expects \type {mu} units is:
+
+\starttyping
+\mugluespecdef\MyGlue = 3mu plus 2mu minus 1mu
+\stoptyping
+
+The properties are comparable to the ones described in the previous sections.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {multiply}}]
+
+The given quantity is multiplied by the given integer (that can be preceded by
+the keyword \quote {by}, like:
+
+\starttyping
+\scratchdimen=10pt \multiply\scratchdimen by 3
+\stoptyping
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {multiplyby}}]
+
+This is slightly more efficient variant of \prm {multiply} that doesn't look for
+\type {by}. See previous section.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {muskip}}]
+
+This is the accessor for an indexed muskip (muglue) register.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {muskipdef}}]
+
+This command associates a control sequence with a muskip (math skip) register
+(accessed by number).
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {mutable}}]
+
+This prefix flags what follows can be adapted and is not subjected to overload
+protection.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {mutoglue}}]
+
+The sequence \typ {\the \mutoglue 20mu plus 10mu minus 5mu} gives \the \mutoglue
+20mu plus 10mu minus 5mu.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {nestedloopiterator}}]
+
+This is one of the accessors of loop iterators:
+
+\startbuffer
+\expandedrepeat 2 {%
+ \expandedrepeat 3 {%
+ (n=\the\nestedloopiterator 1,
+ p=\the\previousloopiterator1,
+ c=\the\currentloopiterator)
+ }%
+}%
+\stopbuffer
+
+\typebuffer
+
+Gives:
+
+\getbuffer
+
+Where a nested iterator starts relative to innermost loop, the previous one is
+relative to the outer loop (which is less predictable because we can already be
+in a loop).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {newlinechar}}]
+
+When something is printed to one of the log channels the character with this code
+will trigger a linebreak. That also resets some counters that deal with
+suppressing redundant ones and possible indentation. Contrary to other engines
+\LUAMETATEX\ doesn't bother about the length of lines.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {noalign}}]
+
+The token list passed to this primitive signals that we don't enter a table row
+yet but for instance in a \prm {halign} do something between the lines: some
+calculation or injecting inter-row material. In \LUAMETATEX\ this primitive can
+be used nested.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {noaligned}}]
+
+The alignment mechanism is kind of special when it comes to expansion because it
+has to look ahead for a \prm {noalign}. This interferes with for instance
+protected macros, but using this prefix we get around that. Among the reasons to
+use protected macros inside an alignment is that they behave better inside for
+instance \prm {expanded}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {noatomruling}}]
+
+Spacing in math is based on classes and this primitive inserts a signal that
+there is no ruling in place here. Basically we have a zero skip glue tagged as
+non breakable because in math mode glue is not a valid breakpoint unless we have
+configured inter|-|class penalties.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {noboundary}}]
+
+This inserts a boundary node with no specific property. It can still serve as
+boundary but is not interpreted in special ways, like the others.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {noexpand}}]
+
+This prefix prevents expansion in a context where expansion happens. Another way
+to prevent expansion is to define a macro as \prm {protected}.
+
+\startbuffer
+ \def\foo{foo} \edef\oof{we expanded \foo} \meaning\oof
+ \def\foo{foo} \edef\oof{we keep \noexpand\foo} \meaning\oof
+\protected\def\foo{foo} \edef\oof{we keep \foo} \meaning\oof
+\stopbuffer
+
+\typebuffer
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {nohrule}}]
+
+This is a rule but flagged as empty which means that the dimensions kick in as
+for a normal rule but the backend can decide not to show it.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {noindent}}]
+
+This starts a paragraph. In \LUATEX\ (and \LUAMETATEX) a paragraph starts with a
+so called par node (see \prm {indent} on how control that. After that comes
+either \prm {parindent} glue or a horizontal box. The \prm {indent} makes gives
+them some width, while \prm {noindent} keeps that zero.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {nolimits}}]
+
+This is a modifier: it flags the previous math atom to have its scripts after the
+the atom (contrary to \prm {limits}. In \LUAMETATEX\ this can be any atom (that
+is: any class). In display mode the location defaults to above and below.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {nonscript}}]
+
+This prevents \TEX\ from adding inter|-|atom glue at this spot in script or
+scriptscript mode. It actually is a special glue itself that serves as signal.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {nonstopmode}}]
+
+This directive omits all stops.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {norelax}}]
+
+The rationale for this command can be shown by a few examples:
+
+\startbuffer
+\dimen0 1pt \dimen2 1pt \dimen4 2pt
+\edef\testa{\ifdim\dimen0=\dimen2\norelax N\else Y\fi}
+\edef\testb{\ifdim\dimen0=\dimen2\relax N\else Y\fi}
+\edef\testc{\ifdim\dimen0=\dimen4\norelax N\else Y\fi}
+\edef\testd{\ifdim\dimen0=\dimen4\relax N\else Y\fi}
+\edef\teste{\norelax}
+\stopbuffer
+
+\typebuffer
+
+The five meanings are:
+
+\start \getbuffer \starttabulate[|T|T|]
+\NC \string\testa \NC \meaning\testa \NC \NR
+\NC \string\testb \NC \meaning\testb \NC \NR
+\NC \string\testc \NC \meaning\testc \NC \NR
+\NC \string\testd \NC \meaning\testd \NC \NR
+\NC \string\teste \NC \meaning\teste \NC \NR
+\stoptabulate \stop
+
+So, the \prm {norelax} acts like \prm {relax} but is not pushed back as
+usual (in some cases).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {normalizelinemode}}]
+
+The \TEX\ engine was not designed to be opened up, and therefore the result of
+the linebreak effort can differ depending on the conditions. For instance not
+every line gets the left- or rightskip. The first and last lines have some unique
+components too. When \LUATEX\ made it possible too get the (intermediate) result
+manipulating the result also involved checking what one encountered, for instance
+glue and its origin. In \LUAMETATEX\ we can normalize lines so that they have for
+instance balanced skips.
+
+\startcolumns[n=2]
+\getbuffer[engine:syntax:normalizelinecodes]
+\stopcolumns
+
+The order in which the skips get inserted when we normalize is as follows:
+
+\starttabulate
+\NC \prm {lefthangskip} \NC the hanging indentation (or zero) \NC \NR
+\NC \prm {leftskip} \NC the value even when zero \NC \NR
+\NC \prm {parfillleftskip} \NC only on the last line \NC \NR
+\NC \prm {parinitleftskip} \NC only on the first line \NC \NR
+\NC \prm {indentskip} \NC the amount of indentation \NC \NR
+\NC \unknown \NC the (optional) content \NC \NR
+\NC \prm {parinitrightskip} \NC only on the first line \NC \NR
+\NC \prm {parfillrightskip} \NC only on the last line \NC \NR
+\NC \prm {correctionskip} \NC the correction needed to stay within the \prm {hsize} \NC \NR
+\NC \prm {rightskip} \NC the value even when zero \NC \NR
+\NC \prm {righthangskip} \NC the hanging indentation (or zero) \NC \NR
+\stoptabulate
+
+The init and fill skips can both show up when we have a single line. The
+correction skip replaces the traditional juggling with the right skip and shift
+of the boxed line.
+
+For now we leave the other options to your imagination. Some of these can be
+achieved by callbacks (as we did in older versions of \CONTEXT) but having the
+engine do the work we get a better performance.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {normalizeparmode}}]
+
+For now we just mention the few options available. It is also worth mentioning that
+\LUAMETATEX\ tries to balance the direction nodes.
+
+\startcolumns[n=2]
+\getbuffer[engine:syntax:normalizeparcodes]
+\stopcolumns
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {nospaces}}]
+
+When \prm {nospaces} is set to~1 no spaces are inserted, when its value is~2 a
+zero space is inserted. The default value is~0 which means that spaces become
+glue with properties depending on the font, specific parameters and|/|or space
+factors determined preceding characters.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {nosubprescript}}]
+
+This processes the given script in the current style, so:
+
+\startbuffer
+$ x___2 + x\nosubprescript{2} + x\subprescript{2} $
+\stopbuffer
+
+comes out as: \inlinebuffer.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {nosubscript}}]
+
+This processes the given script in the current style, so:
+
+\startbuffer
+$ x_2 + x\nosubscript{2} + x\subscript{2} $
+\stopbuffer
+
+comes out as: \inlinebuffer.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {nosuperprescript}}]
+
+This processes the given script in the current style, so:
+
+\startbuffer
+$ x^^^2 + x\nosuperprescript{2} + x\superprescript{2} $
+\stopbuffer
+
+comes out as: \inlinebuffer.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {nosuperscript}}]
+
+This processes the given script in the current style, so:
+
+\startbuffer
+$ x^2 + x\nosuperprescript{2} + x\superprescript{2} $
+\stopbuffer
+
+comes out as: \inlinebuffer.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {novrule}}]
+
+This is a rule but flagged as empty which means that the dimensions kick in as
+for a normal rule but the backend can decide not to show it.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {nulldelimiterspace}}]
+
+In fenced math delimiters can be invisible in which case this parameter
+determines the amount of space (width) that ghost delimiter takes.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {nullfont}}]
+
+This a symbolic reference to a font with no glyphs and a minimal set of font
+dimensions.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {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 \prm {the} primitive does the same, but when you're
+not sure if what follows is a verbose number or (for instance) a counter the
+\prm {number} primitive is a safer bet, because \type {\the 65} will not work.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {numericscale}}]
+
+This primitive can best be explained by a few examples:
+
+\startbuffer
+\the\numericscale 1323
+\the\numericscale 1323.0
+\the\numericscale 1.323
+\the\numericscale 13.23
+\stopbuffer
+
+\typebuffer
+
+In several places \TEX\ uses a scale but due to the lack of floats it then uses
+1000 as 1.0 replacement. This primitive can be used for \quote {real} scales:
+
+\startlines \getbuffer \stoplines
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {numericscaled}}]
+
+This is a variant if \prm {numericscale}:
+
+\startbuffer
+\scratchcounter 1000
+\the\numericscaled 1323 \scratchcounter
+\the\numericscaled 1323.0 \scratchcounter
+\the\numericscaled 1.323 \scratchcounter
+\the\numericscaled 13.23 \scratchcounter
+\stopbuffer
+
+\typebuffer
+
+The second number gets multiplied by the first fraction:
+
+\startlines \getbuffer \stoplines
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {numexpr}}]
+
+This primitive was introduced by \ETEX\ and supports a simple expression syntax:
+
+\startbuffer
+\the\numexpr 10 * (1 + 2 - 5) / 2 \relax
+\stopbuffer
+
+\typebuffer
+
+gives: \inlinebuffer. You can mix in symbolic integers and dimensions.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {numexpression}}]
+
+The normal \prm {numexpr} primitive understands the \type {+}, \type {-}, \type
+{*} and \type {/} operators but in \LUAMETATEX\ we also can use \type {:} for a
+non rounded integer division (think of \LUA's \type {//}). if you want more than
+that, you can use the new expression primitive where you can use the following
+operators.
+
+\starttabulate[||cT|cT|]
+\BC add \NC + \NC \NC \NR
+\BC subtract \NC - \NC \NC \NR
+\BC multiply \NC * \NC \NC \NR
+\BC divide \NC / : \NC \NC \NR
+\BC mod \NC \letterpercent \NC mod \NC \NR
+\BC band \NC & \NC band \NC \NR
+\BC bxor \NC ^ \NC bxor \NC \NR
+\BC bor \NC \letterbar \space v \NC bor \NC \NR
+\BC and \NC && \NC and \NC \NR
+\BC or \NC \letterbar\letterbar \NC or \NC \NR
+\BC setbit \NC <undecided> \NC bset \NC \NR
+\BC resetbit \NC <undecided> \NC breset \NC \NR
+\BC left \NC << \NC \NC \NR
+\BC right \NC >> \NC \NC \NR
+\BC less \NC < \NC \NC \NR
+\BC lessequal \NC <= \NC \NC \NR
+\BC equal \NC = == \NC \NC \NR
+\BC moreequal \NC >= \NC \NC \NR
+\BC more \NC > \NC \NC \NR
+\BC unequal \NC <> != \lettertilde = \NC \NC \NR
+\BC not \NC ! \lettertilde \NC not \NC \NR
+\stoptabulate
+
+An example of the verbose bitwise operators is:
+
+\starttyping
+\scratchcounter = \numexpression
+ "00000 bor "00001 bor "00020 bor "00400 bor "08000 bor "F0000
+\relax
+\stoptyping
+
+In the table you might have notices that some operators have equivalents. This
+makes the scanner a bit less sensitive for catcode regimes.
+
+When \prm {tracingexpressions} is set to one or higher the intermediate \quote
+{reverse polish notation} stack that is used for the calculation is shown, for
+instance:
+
+\starttyping
+4:8: {numexpression rpn: 2 5 > 4 5 > and}
+\stoptyping
+
+When you want the output on your console, you need to say:
+
+\starttyping
+\tracingexpressions 1
+\tracingonline 1
+\stoptyping
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {omit}}]
+
+This primitive cancels the template set for the upcoming cell. Often it is used
+in combination with \prm {span}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {optionalboundary}}]
+
+This boundary is used to mark optional content. An positive \prm
+{optionalboundary} starts a range and a zero one ends it. Nesting is not
+supported. Optional content is considered when an additional paragraph pass
+enables it as part of its recipe.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {or}}]
+
+This traditional primitive is part of the condition testing mechanism and relates
+to an \prm {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
+\prm {or} is seen, then it will continue expanding till it sees a \prm {or}
+or \prm {else} or \prm {orelse} (to be discussed later). It will then do a
+fast skipping pass till it sees an \prm {fi}.
\stopoldprimitive
@@ -2244,6 +9061,22 @@ masters \TEX\ might hurt.
\stopnewprimitive
+\startnewprimitive[title={\prm {orphanpenalties}}]
+
+This an (single entry) array parameter: first the size is given followed by that
+amount of penalties. These penalties are injected before spaces, going backward
+from the end of a paragraph. When we see a math node with a penalty set then we
+take the max and jump over a (preceding) skip.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {orphanpenalty}}]
+
+This penalty is inserted before the last space in a paragraph, unless \prm
+{orphanpenalties} mandates otherwise.
+
+\stopnewprimitive
+
\startnewprimitive[title={\prm {orunless}}]
This is the negated variant of \prm {orelse} (prefixing that one with \tex
@@ -2251,144 +9084,729 @@ This is the negated variant of \prm {orelse} (prefixing that one with \tex
\stopnewprimitive
-\startoldprimitive[title={\prm {futurelet}}]
+\startoldprimitive[title={\prm {outer}}][obsolete=yes]
-The original \TEX\ primitive \prm {futurelet} can be used to create an alias to a next token,
-push it back into the input and then expand a given token.
+An outer macro is one that can only be used at the outer level. This property is
+no longer supported. Like \prm {long}, the \prm {outer} prefix is now an
+no|-|op (and we don't expect this to have unfortunate side effects).
-\startbuffer
-\let\MySpecialToken[
-\def\DoWhatever{\ifx\NextToken\MySpecialToken YES\else NOP\fi : }
-\futurelet\NextToken\DoWhatever [A]\crlf
-\futurelet\NextToken\DoWhatever (A)\par
-\stopbuffer
+\stopoldprimitive
-\typebuffer
+\startoldprimitive[title={\prm {output}}]
-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.
+This token list register holds the code that will be expanded when \TEX\ enters
+the output routine. That code is supposed to do something with the content in
+the box with number \prm {outputbox}. By default this is box 255 but that can be
+changed with \prm {outputbox}.
-{\getbuffer}
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {outputbox}}]
+
+This is where the split off page contend ends up when the output routine is
+triggered.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {outputpenalty}}]
+
+This is the penalty that triggered the output routine.
\stopoldprimitive
-\startnewprimitive[title={\prm {futuredef}}]
+\startoldprimitive[title={\prm {over}}][obsolete=yes]
-We elaborate on the example of using \prm {futurelet} in the previous section.
-Compare that one with the next:
+This math primitive is actually a bit of a spoiler for the parser as it is one of
+the few that looks back. The \prm {Uover} variant is different and takes two
+arguments. We leave it to the user to predicts the results of:
-\startbuffer
-\def\MySpecialToken{[}
-\def\DoWhatever{\ifx\NextToken\MySpecialToken YES\else NOP\fi : }
-\futurelet\NextToken\DoWhatever [A]\crlf
-\futurelet\NextToken\DoWhatever (A)\par
+\starttyping
+$ {1} \over {x} $
+$ 1 \over x $
+$ 12 \over x / y $
+$ a + 1 \over {x} $
+\stoptyping
+
+and:
+
+\starttyping
+$ \textstyle 1 \over x $
+$ {\textstyle 1} \over x $
+$ \textstyle {1 \over x} $
+\stoptyping
+
+It's one of the reasons why macro packages provide \type {\frac}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {overfullrule}}]
+
+When an overfull box is encountered a rule can be shown in the margin and this
+parameter sets its width. For the record: \CONTEXT\ does it different.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {overline}}]
+
+This is a math specific primitive that draws a line over the given content. It is
+a poor mans replacement for a delimiter. The thickness is set with \prm
+{Umathoverbarrule}, the distance between content and rule is set by \prm
+{Umathoverbarvgap} and \prm {Umathoverbarkern} is added above the rule. The style
+used for the content under the rule can be set with \prm {Umathoverlinevariant}.
+
+Because \CONTEXT\ set up math in a special way, the following example:
+
+\startbuffer[demo]
+\normaloverline {
+ \blackrule[color=red, height=1ex,depth=0ex,width=2cm]%
+ \kern-2cm
+ \blackrule[color=blue,height=0ex,depth=.5ex,width=2cm]
+ x + x
+}
\stopbuffer
-\typebuffer
+\typebuffer[demo]
-This time we get:
+gives: \ruledhbox {$\getbuffer[demo]$}, while:
-{\getbuffer}
+\startbuffer[setup]
+\mathfontcontrol\zerocount
+\Umathoverbarkern\allmathstyles10pt
+\Umathoverbarvgap\allmathstyles5pt
+\Umathoverbarrule\allmathstyles2.5pt
+\Umathoverlinevariant\textstyle\scriptstyle
+\stopbuffer
-It is for that reason that we now also have \prm {futuredef}:
+\typebuffer[setup]
+
+gives this: \ruledhbox {$\getbuffer[setup,demo]$}. We have to disable the related
+\prm {mathfontcontrol} bits because otherwise the thickness is taken from the font. The
+variant is just there to overload the (in traditional \TEX\ engines) default.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {overloaded}}]
+
+This prefix can be used to overload a frozen macro.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {overloadmode}}]
+
+The overload protection mechanism can be used to prevent users from redefining
+a control sequence. The mode can have several values, the higher the more strict
+we are:
+
+\starttabulate[||||||||]
+ \NC \NC \NC immutable \NC permanent \NC primitive \NC frozen \NC instance \NC \NR
+ \NC 1 \NC warning \NC + \NC + \NC + \NC \NC \NC \NR
+ \NC 2 \NC error \NC + \NC + \NC + \NC \NC \NC \NR
+ \NC 3 \NC warning \NC + \NC + \NC + \NC + \NC \NC \NR
+ \NC 4 \NC error \NC + \NC + \NC + \NC + \NC \NC \NR
+ \NC 5 \NC warning \NC + \NC + \NC + \NC + \NC + \NC \NR
+ \NC 6 \NC error \NC + \NC + \NC + \NC + \NC + \NC \NR
+\stoptabulate
+
+When you set a high error value, you can of course temporary lower or even zero
+the mode. In \CONTEXT\ all macros and quantities are tagged so there setting the
+mode to~6 gives a proper protection against overloading. We need to zero the mode
+when we load for instance tikz, so when you use that generic package, you loose
+some.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {overshoot}}]
+
+This primitive is a companion to \prm {badness} and reports how much a box
+overflows.
\startbuffer
-\def\MySpecialToken{[}
-\def\DoWhatever{\ifx\NextToken\MySpecialToken YES\else NOP\fi : }
-\futuredef\NextToken\DoWhatever [A]\crlf
-\futuredef\NextToken\DoWhatever (A)\par
+\setbox0\hbox to 1em {mmm} \the\badness\quad\the\overshoot
+\setbox0\hbox {mm} \the\badness\quad\the\overshoot
+\setbox0\hbox to 3em {m} \the\badness\quad\the\overshoot
\stopbuffer
\typebuffer
-So we're back to what we want:
+This reports:
-{\getbuffer}
+\startlines
+\getbuffer
+\stoplines
+
+When traditional \TEX\ wraps up the lines in a paragraph it uses a mix of shift
+(a box property) to position the content suiting the hanging indentation and|/|or
+paragraph shape, and fills up the line using right skip glue, also in order to
+silence complaints in packaging. In \LUAMETATEX\ the lines can be normalized so
+that they all have all possible skips to the left and right (even if they're
+zero). The \prm {overshoot} primitive fits into this picture and is present as a
+compensation glue. This all fits better in a situation where the internals are
+opened up via \LUA.
\stopnewprimitive
-\startnewprimitive[title={\prm {futurecsname}}]
+\startoldprimitive[title={\prm {overwithdelims}}][obsolete=yes]
-In order to make the repertoire of \type {def}, \type {let} and \type {futurelet}
-primitives complete we also have:
+This is a variant of \prm {over} but with delimiters. It has a more advanced
+upgrade in \prm {Uoverwithdelims}.
-\starttyping
-\futurecsname MyMacro:1\endcsname\MyAction
-\stoptyping
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {pageboundary}}]
+
+In order to avoid side effects of triggering the page builder with a specific
+penalty we can use this primitive which expects a value that actually gets
+inserted as zero penalty before triggering the page builder callback. Think of
+adding a no|-|op to the contribution list. We fake a zero penalty so that all
+gets processed. The main rationale is that we get a better indication of what we
+do. Of course a callback can remove this node so that it is never seen.
+Triggering from the callback is not doable. Consider this experimental code
+(which is actually used in \CONTEXT\ anyway).
\stopnewprimitive
-\startnewprimitive[title={\prm {letcharcode}}]
+\startnewprimitive[title={\prm {pagedepth}}]
-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:
+This page property holds the depth of the page.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {pagediscards}}]
+
+The left|-|overs after a page is split of the main vertical list when glue and
+penalties are normally discarded. The discards can be pushed back in (for
+instance) trial runs.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {pageexcess}}]
+
+This page property hold the amount of overflow when a page break occurs.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pageextragoal}}]
+
+This (experimental) dimension will be used when the page overflows but a bit of
+overshoot is considered okay.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {pagefilllstretch}}]
+
+The accumulated amount of third order stretch on the current page.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {pagefillstretch}}]
+
+The accumulated amount of second order stretch on the current page.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {pagefilstretch}}]
+
+The accumulated amount of first order stretch on the current page.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {pagefistretch}}]
+
+The accumulated amount of zero order stretch on the current page.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {pagegoal}}]
+
+The target height of a page (the running text). This value will be decreased by
+the height of inserts something to keep into mind when messing around with this
+and other (pseudo) page related parameters like \prm {pagetotal}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {pagelastdepth}}]
+
+The accumulated depth of the current page.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pagelastfilllstretch}}]
+
+The accumulated amount of third order stretch on the current page. Contrary to
+\prm {pagefilllstretch} this is the really contributed amount, not the upcoming.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pagelastfillstretch}}]
+
+The accumulated amount of second order stretch on the current page. Contrary to
+\prm {pagefillstretch} this is the really contributed amount, not the upcoming.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pagelastfilstretch}}]
+
+The accumulated amount of first order stretch on the current page. Contrary to
+\prm {pagefilstretch} this is the really contributed amount, not the upcoming.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pagelastfistretch}}]
+
+The accumulated amount of zero order stretch on the current page. Contrary to
+\prm {pagefistretch} this is the really contributed amount, not the upcoming.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pagelastheight}}]
+
+The accumulated height of the current page.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pagelastshrink}}]
+
+The accumulated amount of shrink on the current page. Contrary to \prm
+{pageshrink} this is the really contributed amount, not the upcoming.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pagelaststretch}}]
+
+The accumulated amount of stretch on the current page. Contrary to \prm
+{pagestretch} this is the really contributed amount, not the upcoming.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {pageshrink}}]
+
+The accumulated amount of shrink on the current page.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {pagestretch}}]
+
+The accumulated amount of stretch on the current page.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {pagetotal}}]
+
+The accumulated page total (height) of the current page.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {pagevsize}}]
+
+This parameter, when set, is used as the target page height. This lessens the
+change of \prm {vsize} interfering.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {par}}]
+
+This is the explicit \quote {finish paragraph} command. Internally we distinguish
+a par triggered by a new line, as side effect of another primitive or this \prm
+{par} command.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {parametercount}}]
+
+The number of parameters passed to the current macro.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {parameterdef}}]
+
+Here is an example of binding a variable to a parameter. The alternative is of
+course to use an \prm {edef}.
\startbuffer
-{\letcharcode 65 1 \catcode 65 13 A : \meaning A}\crlf
-{\letcharcode 65 2 \catcode 65 13 A : \meaning A}\par
+\def\foo#1#2%
+ {\parameterdef\MyIndexOne\plusone % 1
+ \parameterdef\MyIndexTwo\plustwo % 2
+ \oof{P}\oof{Q}\oof{R}\norelax}
+
+\def\oof#1%
+ {<1:\MyIndexOne><1:\MyIndexOne>%
+ #1%
+ <2:\MyIndexTwo><2:\MyIndexTwo>}
+
+\foo{A}{B}
\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.
+The outcome is:
-{\tttf \getbuffer}
+\getbuffer
-Normally one will assign a control sequence:
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {parameterindex}}]
+
+This gives the zero based position on the parameter stack. One reason for
+introducing \prm {parameterdef} is that the position remains abstract so there we
+don't need to use \prm {parameterindex}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {parametermark}}]
+
+This is an equivalent for \type {#}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {parametermode}}]
+
+Setting this internal integer to a positive value (best use~1 because future
+versions might use bit set) will enable the usage of \type {#} for escaped in the
+main text and body of macros.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {parattribute}}]
+
+This primitive takes an attribute index and value and sets that attribute on the
+current paragraph.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pardirection}}]
+
+This set the text direction for the whole paragraph which in the case of \type
+{r2l} (1) makes the right edge the starting point.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {parfillleftskip}}]
+
+The glue inserted at the start of the last line.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {parfillrightskip}}]
+
+The glue inserted at the end of the last line (aka \prm {parfillskip}).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {parfillskip}}]
+
+The glue inserted at the end of the last line.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {parindent}}]
+
+The amount of space inserted at the start of the first line. When bit \tobit
+\parindentskipnormalizecode\ is set in \prm {normalizelinemode} a glue is
+inserted, otherwise an empty \prm {hbox} with the given width is inserted.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {parinitleftskip}}]
+
+The glue inserted at the start of the first line.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {parinitrightskip}}]
+
+The glue inserted at the end of the first line.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {parpasses}}]
+
+Specifies one or more recipes for additional second linebreak passes. Examples
+can be found in the \CONTEXT\ distribution.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {parshape}}]
+
+Stores a shape specification. The first argument is the length of the list,
+followed by that amount of indentation|-|width pairs (two dimensions).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {parshapedimen}}]
+
+This oddly named (\ETEX) primitive returns the width component (dimension) of the
+given entry (an integer). Obsoleted by \prm {parshapewidth}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {parshapeindent}}]
+
+Returns the indentation component (dimension) of the given entry (an integer).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {parshapelength}}]
+
+Returns the number of entries (an integer).
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {parshapewidth}}]
+
+Returns the width component (dimension) of the given entry (an integer).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {parskip}}]
+
+This is the amount of glue inserted before a new paragraph starts.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {patterns}}]
+
+The argument to this primitive contains hyphenation patterns that are bound to
+the current language. In \LUATEX\ and \LUAMETATEX\ we can also manage this at the
+\LUA\ end. In \LUAMETATEX\ we don't store patterns in te format file
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {pausing}}][obsolete=yes]
+
+In \LUAMETATEX\ this variable is ignored but in other engines it can be used to
+single step thought the input file by setting it to a positive value.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {penalty}}]
+
+The given penalty (a number) is inserted at the current spot in the horizontal or
+vertical list. We also have \prm {vpenalty} and \prm {hpenalty} that first change
+modes.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {permanent}}]
+
+This is one of the prefixes that is part of the overload protection mechanism. It
+is normally used to flag a macro as being at the same level as a primitive: don't
+touch it. primitives are flagged as such but that property cannot be set on
+regular macros. The similar \prm {immutable} flag is normally used for variables.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pettymuskip}}]
+
+A predefined mu skip register that can be used in math (inter atom) spacing. The
+current value is {\tt \the\pettymuskip}. This one complements \prm {thinmuskip},
+\prm {medmuskip}, \prm {thickmuskip} and the new \prm {tinymuskip}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {positdef}}]
+
+The engine uses 32 bit integers for various purposes and has no (real) concept of
+a floating point quantity. We get around this by providing a floating point data
+type based on 32 bit unums (posits). These have the advantage over native floats
+of more precision in the lower ranges but at the cost of a software
+implementation.
+
+The \prm {positdef} primitive is the floating point variant of \prm {integerdef}
+and \prm {dimensiondef}: an efficient way to implement named quantities other
+than registers.
\startbuffer
-{\letcharcode 66 \bf \catcode 66 13 {B bold}: \meaning B}\crlf
-{\letcharcode 73 \it \catcode 73 13 {I italic}: \meaning I}\par
+\positdef \MyFloatA 5.678
+\positdef \MyFloatB 567.8
+[\the\MyFloatA] [\todimension\MyFloatA] [\tointeger\MyFloatA]
+[\the\MyFloatB] [\todimension\MyFloatB] [\tointeger\MyFloatB]
\stopbuffer
\typebuffer
-Of course \type {\bf} and \type {\it} are \CONTEXT\ specific commands:
+For practical reasons we can map posit (or float) onto an integer or dimension:
-{\tttf \getbuffer}
+\startlines
+\getbuffer
+\stoplines
+
+% {\em I might eventually decide to go for 32 bit floats but it all depends on how
+% unums evolve cq. become native to \CCODE.}
\stopnewprimitive
-\startoldprimitive[title={\prm {global}}]
+\startoldprimitive[title={\prm {postdisplaypenalty}}]
-This is one of the original prefixes that can be used when we define a macro of
-change some register.
+This is the penalty injected after a display formula.
-\starttyping
-\bgroup
- \def\MyMacroA{a}
-\global\def\MyMacroB{a}
- \gdef\MyMacroC{a}
-\egroup
-\stoptyping
+\stopoldprimitive
-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.
+\startnewprimitive[title={\prm {postexhyphenchar}}]
+
+This primitive expects a language number and a character code. A negative
+character code is equivalent to ignore. In case of an explicit discretionary the
+character is injected at the beginning of a new line.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {posthyphenchar}}]
+
+This primitive expects a language number and a character code. A negative
+character code is equivalent to ignore. In case of an automatic discretionary the
+character is injected at the beginning of a new line.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {postinlinepenalty}}]
+
+When set this penalty is inserted after an inline formula unless we have a short
+formula and \prm {postshortinlinepenalty} is set.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {postshortinlinepenalty}}]
+
+When set this penalty is inserted after a short inline formula. The criterium is
+set by \prm {shortinlinemaththreshold} but only applied when it is enabled for
+the class involved.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {prebinoppenalty}}]
+
+This internal quantity is a compatibility feature because normally we will use
+the inter atom spacing variables.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {predisplaydirection}}]
+
+This is the direction that the math sub engine will take into account when
+dealing with right to left typesetting.
\stopoldprimitive
-\startoldprimitive[title={\prm {long}}]
+\startnewprimitive[title={\prm {predisplaygapfactor}}]
-This original prefix gave the macro being defined the property that it could not
-have \prm {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).
+The heuristics related to determine if the previous line in a formula overlaps
+with a (display) formula are hard coded but in \LUATEX\ to be two times the quad
+of the current font. This parameter is a multiplier set to 2000 and permits you
+to change the overshoot in this heuristic.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {predisplaypenalty}}]
+
+This is the penalty injected before a display formula.
\stopoldprimitive
-\startoldprimitive[title={\prm {outer}}]
+\startoldprimitive[title={\prm {predisplaysize}}]
-An outer macro is one that can only be used at the outer level. This property is
-no longer supported. Like \prm {long}, the \prm {outer} prefix is now an
-no|-|op (and we don't expect this to have unfortunate side effects).
+This parameter holds the length of the last line in a paragraph when a display
+formula is part of it.
\stopoldprimitive
+\startnewprimitive[title={\prm {preexhyphenchar}}]
+
+This primitive expects a language number and a character code. A negative
+character code is equivalent to ignore. In case of an explicit discretionary the
+character is injected at the end of the line.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {prehyphenchar}}]
+
+This primitive expects a language number and a character code. A negative
+character code is equivalent to ignore. In case of an automatic discretionary the
+character is injected at the end of the line.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {preinlinepenalty}}]
+
+When set this penalty is inserted before an inline formula unless we have a short
+formula and \prm {preshortinlinepenalty} is set.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {prerelpenalty}}]
+
+This internal quantity is a compatibility feature because normally we will use
+the inter atom spacing variables.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {preshortinlinepenalty}}]
+
+When set this penalty is inserted before a short inline formula. The criterium is
+set by \prm {shortinlinemaththreshold} but only applied when it is enabled for
+the class involved.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {pretolerance}}]
+
+When the badness of a line in a paragraph exceeds this value a second linebreak
+pass will be enabled.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {prevdepth}}]
+
+The depth of current list. It can also be set to special (signal) values in order
+to inhibit line corrections. It is not an internal dimension but a (current) list
+property.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {prevgraf}}]
+
+The number of lines in a previous paragraph.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {previousloopiterator}}]
+
+\startbuffer
+\edef\testA{
+ \expandedrepeat 2 {%
+ \expandedrepeat 3 {%
+ (\the\previousloopiterator1:\the\currentloopiterator)
+ }%
+ }%
+}
+\edef\testB{
+ \expandedrepeat 2 {%
+ \expandedrepeat 3 {%
+ (#P:#I) % #G is two levels up
+ }%
+ }%
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+These give the same result:
+
+\startlines \tt
+\meaningasis\testA
+\meaningasis\testB
+\stoplines
+
+The number indicates the number of levels we go up the loop chain.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {primescript}}]
+
+This is a math script primitive dedicated to primes (which are somewhat
+troublesome on math). It complements the six script primitives (like \prm
+{subscript} and \prm {presuperscript}).
+
+\stopnewprimitive
+
\startoldprimitive[title={\prm {protected}}]
A protected macro is one that doesn't get expanded unless it is time to do so.
@@ -2402,441 +9820,1465 @@ also defined but it has been dropped.
\stopoldprimitive
-\startnewprimitive[title={\prm {expand}}]
+\startnewprimitive[title={\prm {protecteddetokenize}}]
-Beware, this is not a prefix but a directive to ignore the protected characters of
-the following macro.
+This is a variant of \prm {protecteddetokenize} that uses some escapes encoded as
+body parameters, like \type {#H} for a hash.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {protectedexpandeddetokenize}}]
+
+This is a variant of \prm {expandeddetokenize} that uses some escapes encoded as
+body parameters, like \type {#H} for a hash.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {protrudechars}}]
+
+This variable controls protrusion (into the margin). A value~2 is comparable with
+other engines, while a value of~3 does a bit more checking when we're doing
+right|-|to|-|left typesetting.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {protrusionboundary}}]
+
+This injects a boundary with the given value:
+
+\getbuffer[engine:syntax:protrusionboundarycodes]
+
+This signal makes the protrusion checker skip over a node.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {pxdimen}}]
+
+The current numeric value of this dimension is \tointeger \pxdimen, \todimension
+\pxdimen: one \type {bp}. We kept it around because it was introduced in \PDFTEX\
+and made it into \LUATEX, where it relates to the resolution of included images.
+In \CONTEXT\ it is not used.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {quitloop}}]
+
+There are several loop primitives and they can be quit with \prm {quitloop} at
+the next the {\em next} iteration. An immediate quit is possible with \prm
+{quitloopnow}. An example is given with \prm {localcontrolledloop}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {quitloopnow}}]
+
+There are several loop primitives and they can be quit with \prm {quitloopnow}
+at the spot.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {quitvmode}}]
+
+This primitive forces horizontal mode but has no side effects when we're already
+in that mode.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {radical}}][obsolete=yes]
+
+This old school radical constructor is replaced by \prm {Uradical}. It takes a
+number where the first byte is the small family, the next two index of this
+symbol from that family, and the next three the family and index of the first
+larger variant.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {raise}}]
+
+This primitive takes two arguments, a dimension and a box. The box is moved up.
+The operation only succeeds in horizontal mode.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {rdivide}}]
+
+This is variant of \prm {divide} that rounds the result. For integers the result
+is the same as \prm {edivide}.
\startbuffer
-\protected \def \testa{\the\scratchcounter}
- \edef\testb{\testa}
- \edef\testc{\expand\testa}
+\the\dimexpr .4999pt : 2 \relax =.24994pt
+\the\dimexpr .4999pt / 2 \relax =.24995pt
+\scratchdimen.4999pt \divide \scratchdimen 2 \the\scratchdimen =.24994pt
+\scratchdimen.4999pt \edivide\scratchdimen 2 \the\scratchdimen =.24995pt
+\scratchdimen 4999pt \rdivide\scratchdimen 2 \the\scratchdimen =2500.0pt
+\scratchdimen 5000pt \rdivide\scratchdimen 2 \the\scratchdimen =2500.0pt
+
+\the\numexpr 1001 : 2 \relax =500
+\the\numexpr 1001 / 2 \relax =501
+\scratchcounter1001 \divide \scratchcounter 2 \the\scratchcounter=500
+\scratchcounter1001 \edivide\scratchcounter 2 \the\scratchcounter=501
+\scratchcounter1001 \rdivide\scratchcounter 2 \the\scratchcounter=501
\stopbuffer
\typebuffer
-The meaning of the three macros is:
-
-\startlines \getbuffer \tttf
-\meaningfull\testa
-\meaningfull\testb
-\meaningfull\testc
+\startlines
+\getbuffer
\stoplines
\stopnewprimitive
-\startnewprimitive[title={\prm {untraced}}]
+\startnewprimitive[title={\prm {rdivideby}}]
-Related to the meaning providers is the \prm {untraced} prefix. It marks a macro
-as to be reported by name only. It makes the macro look like a primitive.
+This is the \type {by}|-|less companion to \prm {rdivide}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {realign}}]
+
+Where \prm {omit} suspends a preamble template, this one overloads is for the
+current table cell. It expects two token lists as arguments.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {relax}}]
+
+This primitive does nothing and is often used to end a verbose number or
+dimension in a comparison, for example:
\starttyping
- \def\foo{}
-\untraced\def\oof{}
+\ifnum \scratchcounter = 123\relax
+\stoptyping
-\scratchtoks{\foo\foo\oof\oof}
+which prevents a lookahead. A variant would be:
-\tracingall \the\scratchtoks \tracingnone
+\starttyping
+\ifnum \scratchcounter = 123 %
\stoptyping
-This will show up in the log as follows:
+assuming that spaces are not ignored. Another application is finishing
+an expression like \prm {numexpr} or \prm {dimexpr}. I is also used
+to prevent lookahead in cases like:
\starttyping
-1:4: {\the}
-1:5: \foo ->
-1:5: \foo ->
-1:5: \oof
-1:5: \oof
+\vrule height 3pt depth 2pt width 5pt\relax
+\hskip 5pt plus 3pt minus 2pt\relax
\stoptyping
-This is again a trick to avoid too much clutter in a log. Often it doesn't matter
-to users what the meaning of a macro is (if they trace at all). \footnote {An
-earlier variant could also hide the expansion completely but that was just
-confusing.}
+Because \prm {relax} is not expandable the following:
-\startoldprimitive[title={\prm {immediate}}]
+\startbuffer
+\edef\foo{\relax} \meaningfull\foo
+\edef\oof{\norelax} \meaningfull\oof
+\stopbuffer
-This one has no effect unless you intercept it at the \LUA\ end and act upon it.
-In original \TEX\ immediate is used in combination with read from and write to
-file operations. So, this is an old primitive with a new meaning.
+\typebuffer
+
+gives this:
+
+\startlines
+\getbuffer
+\stoplines
+
+A \prm {norelax} disappears here but in the previously mentioned scenarios
+it has the same function as \prm {relax}. It will not be pushed back either
+in cases where a lookahead demands that.
\stopoldprimitive
-\startnewprimitive[title={\prm {frozen}}]
+\startoldprimitive[title={\prm {relpenalty}}]
-You can define a macro as being frozen:
+This internal quantity is a compatibility feature because normally we will use
+the inter atom spacing variables.
-\starttyping
-\frozen\def\MyMacro{...}
-\stoptyping
+\stopoldprimitive
-When you redefine this macro you get an error:
+\startnewprimitive[title={\prm {resetmathspacing}}]
+
+This initializes all parameters to their initial values.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {restorecatcodetable}}]
+
+This is an experimental feature that should be used with care. The next example
+shows usage. It was added when debugging and exploring a side effect.
\starttyping
-! You can't redefine a frozen macro.
-\stoptyping
+\tracingonline1
-This is a prefix like \prm {global} and it can be combined with other prefixes.
-\footnote {The \prm {outer} and \prm {long} prefixes are no|-|ops in
-\LUAMETATEX\ and \LUATEX\ can be configured to ignore them.}
+\bgroup
-\stopnewprimitive
+ \catcode`6 = 11 \catcode`7 = 11
-\startnewprimitive[title={\prm {letfrozen}}]
+ \bgroup
-You can explicitly freeze an unfrozen macro:
+ \tracingonline1
+
+ current: \the\catcodetable
+
+ original: \the\catcode`6\quad \the\catcode`7
+
+ \catcode`6 = 11 \catcode`7 = 11
+
+ \showcodestack\catcode
+
+ assigned: \the\catcode`6\quad \the\catcode`7
+
+ \showcodestack\catcode
+
+ \catcodetable\ctxcatcodes switched: \the\catcodetable
+
+ stored: \the\catcode`6\quad \the\catcode`7
+
+ \showcodestack\catcode
+
+ \restorecatcodetable\ctxcatcodes
+
+ \showcodestack\catcode
+
+ restored: \the\catcode`6\quad \the\catcode`7
+
+ \showcodestack\catcode
+
+ \egroup
+
+ \catcodetable\ctxcatcodes
+
+ inner: \the\catcode`6\quad\the\catcode`7
+
+\egroup
+
+outer: \the\catcode`6\quad\the\catcode`7
+\stoptyping
+
+In \CONTEXT\ this typesets:
\starttyping
-\def\MyMacro{...}
-\letfrozen\MyMacro
+current: 9
+original: 11 11
+assigned: 11 11
+switched: 9
+stored: 11 11
+restored: 12 12
+inner: 11 11
+outer; 12 12
\stoptyping
-A redefinition will now give:
+and on the console we see:
\starttyping
-! You can't redefine a frozen macro.
+3:3: [codestack 1, size 3]
+3:3: [1: level 2, code 54, value 12]
+3:3: [2: level 2, code 55, value 12]
+3:3: [3: level 3, code 54, value 11]
+3:3: [4: level 3, code 55, value 11]
+3:3: [codestack 1 bottom]
+3:3: [codestack 1, size 3]
+3:3: [1: level 2, code 54, value 12]
+3:3: [2: level 2, code 55, value 12]
+3:3: [3: level 3, code 54, value 11]
+3:3: [4: level 3, code 55, value 11]
+3:3: [codestack 1 bottom]
+3:3: [codestack 1, size 3]
+3:3: [1: level 2, code 54, value 12]
+3:3: [2: level 2, code 55, value 12]
+3:3: [3: level 3, code 54, value 11]
+3:3: [4: level 3, code 55, value 11]
+3:3: [codestack 1 bottom]
+3:3: [codestack 1, size 7]
+3:3: [1: level 2, code 54, value 12]
+3:3: [2: level 2, code 55, value 12]
+3:3: [3: level 3, code 54, value 11]
+3:3: [4: level 3, code 55, value 11]
+3:3: [5: level 3, code 55, value 11]
+3:3: [6: level 3, code 54, value 11]
+3:3: [7: level 3, code 55, value 11]
+3:3: [8: level 3, code 54, value 11]
+3:3: [codestack 1 bottom]
+3:3: [codestack 1, size 7]
+3:3: [1: level 2, code 54, value 12]
+3:3: [2: level 2, code 55, value 12]
+3:3: [3: level 3, code 54, value 11]
+3:3: [4: level 3, code 55, value 11]
+3:3: [5: level 3, code 55, value 11]
+3:3: [6: level 3, code 54, value 11]
+3:3: [7: level 3, code 55, value 11]
+3:3: [8: level 3, code 54, value 11]
+3:3: [codestack 1 bottom]
\stoptyping
+So basically \prm {restorecatcodetable} brings us (temporarily) back to the
+global settings.
+
\stopnewprimitive
-\startnewprimitive[title={\prm {unletfrozen}}]
+\startnewprimitive[title={\prm {retained}}]
-A frozen macro cannot be redefined: you get an error. But as nothing in \TEX\ is set
-in stone, you can do this:
+When a value is assigned inside a group \TEX\ pushes the current value on the save
+stack in order to be able to restore the original value after the group has ended. You
+can reach over a group by using the \prm {global} prefix. A mix between local and
+global assignments can be achieved with the \prm {retained} primitive.
-\starttyping
-\frozen\def\MyMacro{...}
-\unletfrozen\MyMacro
-\stoptyping
+\newdimension\MyDim
-and \type {\MyMacro} is no longer protected from overloading. It is still
-undecided to what extend \CONTEXT\ will use this feature.
+\startbuffer[one]
+\MyDim 15pt \bgroup \the\MyDim \space
+\bgroup
+ \bgroup
+ \bgroup \advance\MyDim10pt \the\MyDim \egroup\space
+ \bgroup \advance\MyDim10pt \the\MyDim \egroup\space
+ \egroup
+ \bgroup
+ \bgroup \advance\MyDim10pt \the\MyDim \egroup\space
+ \bgroup \advance\MyDim10pt \the\MyDim \egroup\space
+ \egroup
+\egroup
+\egroup \the\MyDim
+\stopbuffer
+
+\startbuffer[two]
+\MyDim 15pt \bgroup \the\MyDim \space
+\bgroup
+ \bgroup
+ \bgroup \global\advance\MyDim10pt \the\MyDim \egroup\space
+ \bgroup \global\advance\MyDim10pt \the\MyDim \egroup\space
+ \egroup
+ \bgroup
+ \bgroup \global\advance\MyDim10pt \the\MyDim \egroup\space
+ \bgroup \global\advance\MyDim10pt \the\MyDim \egroup\space
+ \egroup
+\egroup
+\egroup \the\MyDim
+\stopbuffer
+
+\startbuffer[three]
+\MyDim 15pt \bgroup \the\MyDim \space
+ \constrained\MyDim\zeropoint
+ \bgroup
+ \bgroup \retained\advance\MyDim10pt \the\MyDim \egroup\space
+ \bgroup \retained\advance\MyDim10pt \the\MyDim \egroup\space
+ \egroup
+ \bgroup
+ \bgroup \retained\advance\MyDim10pt \the\MyDim \egroup\space
+ \bgroup \retained\advance\MyDim10pt \the\MyDim \egroup\space
+ \egroup
+\egroup \the\MyDim
+\stopbuffer
+
+\typebuffer[one,two,three]
+
+These lines result in:
+
+\startlines
+\hbox{\getbuffer[one]}
+\hbox{\getbuffer[two]}
+\hbox{\getbuffer[three]}
+\stoplines
+
+Because \LUAMETATEX\ avoids redundant stack entries and reassignments this
+mechanism is a bit fragile but the \prm {constrained} prefix makes sure that we
+do have a stack entry. If it is needed depends on the usage pattern.
\stopnewprimitive
-\startnewprimitive[title={\prm {letprotected}}]
+\startnewprimitive[title={\prm {retokenized}}]
-Say that you have these definitions:
+This is a companion of \prm {tokenized} that accepts a catcode table, so the
+whole repertoire is:
\startbuffer
- \def \MyMacroA{alpha}
-\protected \def \MyMacroB{beta}
- \edef \MyMacroC{\MyMacroA\MyMacroB}
-\letprotected \MyMacroA
- \edef \MyMacroD{\MyMacroA\MyMacroB}
-\meaning \MyMacroC\crlf
-\meaning \MyMacroD\par
+\tokenized {test $x$ test: current}
+\tokenized catcodetable \ctxcatcodes {test $x$ test: context}
+\tokenized catcodetable \vrbcatcodes {test $x$ test: verbatim}
+\retokenized \ctxcatcodes {test $x$ test: context}
+\retokenized \vrbcatcodes {test $x$ test: verbatim}
\stopbuffer
\typebuffer
-The typeset meaning in this example is:
+Here we pass the numbers known to \CONTEXT\ and get:
-{\tttf \getbuffer}
+\startlines
+\getbuffer
+\stoplines
\stopnewprimitive
-\startnewprimitive[title={\prm {unletprotected}}]
+\startoldprimitive[title={\prm {right}}]
-The complementary operation of \prm {letprotected} can be used to unprotect
-a macro, so that it gets expandable.
+Inserts the given delimiter as right fence in a math formula.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {righthyphenmin}}]
+
+This is the minimum number of characters before the first hyphen in a hyphenated
+word.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {rightmarginkern}}]
+
+The dimension returned is the protrusion kern that has been added (if at all) to
+the left of the content in the given box.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {rightskip}}]
+
+This skip will be inserted at the right of every line.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {romannumeral}}]
+
+This converts a number into a sequence of characters representing a roman
+numeral. Because the Romans had no zero, a zero will give no output, a fact that
+is sometimes used for hacks and showing off ones macro coding capabilities. A
+large number will for sure result in a long string because after thousand we
+start duplicating.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {rpcode}}]
+
+This is the companion of \prm {lpcode} (see there) and also takes three
+arguments: font, character code and factor.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {savecatcodetable}}]
+
+This primitive stores the currently set catcodes in the current table.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {savinghyphcodes}}]
+
+When set to non|-|zero, this will trigger the setting of \prm {hjcode}s from \prm
+{lccode}s for the current font. These codes determine what characters are taken
+into account when hyphenating words.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {savingvdiscards}}]
+
+When set to a positive value the page builder will store the discarded items
+(like glues) so that they can later be retrieved and pushed back if needed with
+\prm {pagediscards} or \prm {splitdiscards}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {scaledemwidth}}]
+
+Returns the current (font specific) emwidth scaled according to \prm {glyphscale}
+and \prm {glyphxscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledexheight}}]
+
+Returns the current (font specific) exheight scaled according to \prm {glyphscale}
+and \prm {glyphyscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledextraspace}}]
+
+Returns the current (font specific) extra space value scaled according to \prm
+{glyphscale} and \prm {glyphxscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledfontcharba}}]
+
+Returns the bottom accent position of the given font|-|character pair scaled
+according to \prm {glyphscale} and \prm {glyphyscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledfontchardp}}]
+
+Returns the depth of the given font|-|character pair scaled according to \prm
+{glyphscale} and \prm {glyphyscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledfontcharht}}]
+
+Returns the height of the given font|-|character pair scaled according to \prm
+{glyphscale} and \prm {glyphyscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledfontcharic}}]
+
+Returns the italic correction of the given font|-|character pair scaled according
+to \prm {glyphscale} and \prm {glyphxscale}. This property is only real for
+traditional fonts.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledfontcharta}}]
+
+Returns the top accent position of the given font|-|character pair scaled
+according to \prm {glyphscale} and \prm {glyphxscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledfontcharwd}}]
+
+Returns width of the given font|-|character pair scaled according to \prm
+{glyphscale} and \prm {glyphxscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledfontdimen}}]
+
+Returns value of a (numeric) font dimension of the given font|-|character pair
+scaled according to \prm {glyphscale} and \prm {glyphxscale} and|/|or \prm
+{glyphyscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledinterwordshrink}}]
+
+Returns the current (font specific) shrink of a space value scaled according to
+\prm {glyphscale} and \prm {glyphxscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledinterwordspace}}]
+
+Returns the current (font specific) space value scaled according to \prm
+{glyphscale} and \prm {glyphxscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledinterwordstretch}}]
+
+Returns the current (font specific) stretch of a space value scaled according to
+\prm {glyphscale} and \prm {glyphxscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledmathaxis}}]
+
+This primitive returns the math axis of the given math style. It's a dimension.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledmathemwidth}}]
+
+Returns the emwidth of the given style scaled according to \prm {glyphscale} and
+\prm {glyphxscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledmathexheight}}]
+
+Returns the exheight of the given style scaled according to \prm {glyphscale} and
+\prm {glyphyscale}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {scaledmathstyle}}]
+
+This command inserts a signal in the math list that tells how to scale the (upcoming)
+part of the formula.
\startbuffer
- \def \MyMacroA{alpha}
-\protected \def \MyMacroB{beta}
- \edef \MyMacroC{\MyMacroA\MyMacroB}
-\unletprotected \MyMacroB
- \edef \MyMacroD{\MyMacroA\MyMacroB}
-\meaning \MyMacroC\crlf
-\meaning \MyMacroD\par
+$ x + {\scaledmathstyle900 x} + x$
\stopbuffer
\typebuffer
-Compare this with the example in the previous section:
-
-{\tttf \getbuffer}
+We get: \inlinebuffer. Of course using this properly demands integration in the macro
+packages font system.
\stopnewprimitive
-% \startnewprimitive[title={\prm {letdatacode}}]
-% {\em Todo.}
-% \stopnewprimitive
+\startnewprimitive[title={\prm {scaledslantperpoint}}]
-\startnewprimitive[title={\prm {beginlocalcontrol}}]
+This primitive is equivalent to \typ {\scaledfontdimen1\font} where \quote
+{scaled} means that we multiply by the glyph scales.
-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.
+\stopnewprimitive
-\startbuffer
-\scratchcounter100
+\startnewprimitive[title={\prm {scantextokens}}]
-\edef\whatever{
- a
- \beginlocalcontrol
- \advance\scratchcounter 10
- b
- \endlocalcontrol
- \beginlocalcontrol
- c
- \endlocalcontrol
- d
- \advance\scratchcounter 10
-}
+This primitive scans the input as if it comes from a file. In the next examples
+the \prm {detokenize} primitive turns tokenized code into verbatim code that is
+similar to what is read from a file.
-\the\scratchcounter
-\whatever
-\the\scratchcounter
+\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}\par
\stopbuffer
\typebuffer
-A bit of close reading probably gives an impression of what happens here:
+This primitive does not have the end|-|of|-|file side effects of its precursor
+\prm {scantokens}.
{\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 \prm
-{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
+
+\startoldprimitive[title={\prm {scantokens}}]
+
+Just forget about this \ETEX\ primitive, just take the one in the next section.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {scriptfont}}]
+
+This primitive is like \prm {font} but with a family number as (first) argument
+so it is specific for math. It is the middle one of the three family members; its
+relatives are \prm {textfont} and \prm {scriptscriptfont}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {scriptscriptfont}}]
+
+This primitive is like \prm {font} but with a family number as (first) argument
+so it is specific for math. It is the smallest of the three family members; its
+relatives are \prm {textfont} and \prm {scriptfont}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {scriptscriptstyle}}]
+
+One of the main math styles, normally one size smaller than \prm {scriptstyle}:
+integer representation: \the\scriptscriptstyle.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {scriptspace}}][obsolete=yes]
+
+The math engine will add this amount of space after subscripts and superscripts.
+It can be seen as compensation for the often too small widths of characters (in
+the traditional engine italic correction is used too). It prevents scripts from
+running into what follows.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {scriptspaceafterfactor}}]
+
+This is a (1000 based) multiplier for \prm {Umathspaceafterscript}.
\stopnewprimitive
-\startnewprimitive[title={\prm {endlocalcontrol}}]
+\startnewprimitive[title={\prm {scriptspacebeforefactor}}]
- See previous section.
+This is a (1000 based) multiplier for \prm {Umathspacebeforescript}.
\stopnewprimitive
-\startnewprimitive[title={\prm {localcontrolled}}]
+\startnewprimitive[title={\prm {scriptspacebetweenfactor}}]
-The previously described local control feature comes with two extra helpers. The
-\prm {localcontrolled} primitive takes a token list and wraps this into a local
-control sidetrack. For example:
+This is a (1000 based) multiplier for \prm {Umathspacebetweenscript}.
-\startbuffer
-\edef\testa{\scratchcounter123 \the\scratchcounter}
-\edef\testb{\localcontrolled{\scratchcounter123}\the\scratchcounter}
-\stopbuffer
+\stopnewprimitive
-\typebuffer
+\startoldprimitive[title={\prm {scriptstyle}}]
-The two meanings are:
+One of the main math styles, normally one size smaller than \prm {displaystyle}
+and \prm {textstyle}; integer representation: \the\scriptstyle.
-\start \getbuffer
-\starttabulate[|T|T|]
-\NC \string\testa \NC \meaningfull\testa \NC \NR
-\NC \string\testb \NC \meaningfull\testb \NC \NR
-\stoptabulate
-\stop
+\stopoldprimitive
-The assignment is applied immediately in the expanded definition.
+\startoldprimitive[title={\prm {scrollmode}}]
+
+ This directive omits error stops.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {semiexpand}}]
+
+This command expands the next macro when it is protected with \prm
+{semprotected}. See that primitive there for an example.
\stopnewprimitive
-\startnewprimitive[title={\prm {localcontrol}}]
+\startnewprimitive[title={\prm {semiexpanded}}]
-This primitive takes a single token:
+This command expands the tokens in the given list including the macros protected
+by with \prm {semprotected}. See that primitive there for an example.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {semiprotected}}]
\startbuffer
-\edef\testa{\scratchcounter123 \the\scratchcounter}
-\edef\testc{\testa \the\scratchcounter}
-\edef\testd{\localcontrol\testa \the\scratchcounter}
+ \def\TestA{A}
+\semiprotected\def\TestB{B}
+ \protected\def\TestC{C}
+
+\edef\TestD{\TestA \TestB \TestC}
+\edef\TestE{\TestA\semiexpand\TestB\semiexpand\TestC}
+\edef\TestF{\TestA\expand \TestB\expand \TestC}
+
+\edef\TestG{\normalexpanded {\TestA\TestB\TestC}}
+\edef\TestH{\normalsemiexpanded{\TestA\TestB\TestC}}
\stopbuffer
-\typebuffer
+The working of this prefix can best be explained with an example. We define a few
+macros first:
-The three meanings are:
+\typebuffer \getbuffer
-\start \getbuffer
-\starttabulate[|T|T|]
-\NC \string\testa \NC \meaning\testa \NC \NR
-\NC \string\testc \NC \meaning\testc \NC \NR
-\NC \string\testd \NC \meaning\testd \NC \NR
-\stoptabulate
-\stop
+The meaning of the macros that are made from the other three are:
-The \prm {localcontrol} makes that the following token gets expanded so we don't
-see the yet to be expanded assignment show up in the macro body.
+\startbuffer
+\meaningless\TestD
+\meaningless\TestE
+\meaningless\TestF
+\meaningless\TestG
+\meaningless\TestH
+\stopbuffer
+
+Here we use the \type {\normal..} variants because (currently) we still have the
+macro with the \type {\expanded} in the \CONTEXT\ core.
+
+\startlines \tttf \getbuffer \stoplines
\stopnewprimitive
-\startnewprimitive[title={\prm {alignmark}}]
+\startoldprimitive[title={\prm {setbox}}]
-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.
+This important primitive is used to set a box register. It expects a number and a
+box, like \prm {hbox} or \prm {box}. There is no \type {\boxdef} primitive
+(analogue to other registers) because it makes no sense but numeric registers or
+equivalents are okay as register value.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {setdefaultmathcodes}}]
+
+This sets the math codes of upper- and lowercase alphabet and digits and the
+delimiter code of the period. It's not so much a useful feature but more just an
+accessor to the internal initializer.
\stopnewprimitive
-\startnewprimitive[title={\prm {aligntab}}]
+\startnewprimitive[title={\prm {setfontid}}]
-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.
+Internally a font instance has a number and this number is what gets assigned to
+a glyph node. You can get the number with \prm {fontid} an set it with \prm
+{setfontid}.
+
+\starttyping
+\setfontid\fontid\font
+\stoptyping
+
+The code above shows both primitives and effectively does nothing useful but
+shows the idea.
\stopnewprimitive
-\startnewprimitive[title={\prm {defcsname}}]
+\startoldprimitive[title={\prm {setlanguage}}]
-We now get a series of log clutter avoidance primitives. It's fine if you argue
-that they are not really needed, just don't use them.
+In \LUATEX\ and \LUAMETATEX\ this is equivalent to \prm {language} because we
+carry the language in glyph nodes instead of putting triggers in the list.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {setmathatomrule}}]
+
+The math engine has some built in logic with respect to neighboring atoms that
+change the class. The following combinations are intercepted and remapped:
+
+\starttabulate[|c|c|c|c|]
+\BC old first \BC old second \NC new first \NC new second \NC \NR
+\ML
+\NC begin \NC binary \NC ordinary \NC ordinary \NC \NR
+\NC \NC \NC \NC \NC \NR
+\NC operator \NC binary \NC operator \NC ordinary \NC \NR
+\NC open \NC binary \NC open \NC ordinary \NC \NR
+\NC punctuation \NC binary \NC punctuation \NC ordinary \NC \NR
+\NC \NC \NC \NC \NC \NR
+\NC binary \NC end \NC ordinary \NC ordinary \NC \NR
+\NC binary \NC binary \NC binary \NC ordinary \NC \NR
+\NC binary \NC close \NC ordinary \NC close \NC \NR
+\NC binary \NC punctuation \NC ordinary \NC punctuation \NC \NR
+\NC binary \NC relation \NC ordinary \NC relation \NC \NR
+\NC \NC \NC \NC \NC \NR
+\NC relation \NC binary \NC relation \NC ordinary \NC \NR
+\NC relation \NC close \NC ordinary \NC close \NC \NR
+\NC relation \NC punctuation \NC ordinary \NC punctuation \NC \NR
+\stoptabulate
+
+You can change this logic if needed, for instance:
\starttyping
-\expandafter\def\csname MyMacro:1\endcsname{...}
- \defcsname MyMacro:1\endcsname{...}
+\setmathatomrule 1 2 \allmathstyles 1 1
\stoptyping
-The fact that \TEX\ has three (expanded and global) companions can be seen as a
-signal that less verbosity makes sense. It's just that macro packages use plenty
-of \prm {csname}'s.
+Keep in mind that the defaults are what users expect. You might set them up for
+additional classes that you define but even then you probably clone an existing
+class and patch its properties. Most extra classes behave like ordinary anyway.
\stopnewprimitive
-\startnewprimitive[title={\prm {edefcsname}}]
+\startnewprimitive[title={\prm {setmathdisplaypostpenalty}}]
-This is the companion of \prm {edef}:
+This penalty is inserted after an item of a given class but only in inline math
+when display style is used, for instance:
\starttyping
-\expandafter\edef\csname MyMacro:1\endcsname{...}
- \edefcsname MyMacro:1\endcsname{...}
+\setmathdisplayprepenalty 2 750
\stoptyping
\stopnewprimitive
-\startnewprimitive[title={\prm {gdefcsname}}]
+\startnewprimitive[title={\prm {setmathdisplayprepenalty}}]
-As with standard \TEX\ we also define global ones:
+This penalty is inserted before an item of a given class but only in inline math
+when display style is used, for instance:
\starttyping
-\expandafter\gdef\csname MyMacro:1\endcsname{...}
- \gdefcsname MyMacro:1\endcsname{...}
+\setmathdisplayprepenalty 2 750
\stoptyping
\stopnewprimitive
-\startnewprimitive[title={\prm {xdefcsname}}]
+\startnewprimitive[title={\prm {setmathignore}}]
-This is the companion of \prm {xdef}:
+You can flag a math parameter to be ignored, like:
\starttyping
-\expandafter\xdef\csname MyMacro:1\endcsname{...}
- \xdefcsname MyMacro:1\endcsname{...}
+\setmathignore \Umathxscale 2
+\setmathignore \Umathyscale 2
+\setmathignore \Umathspacebeforescript 1
+\setmathignore \Umathspacebetweenscript 1
+\setmathignore \Umathspaceafterscript 1
\stoptyping
+A value of two will not initialize the variable, so its old value (when set) is
+kept. This is somewhat experimental and more options might show up.
+
\stopnewprimitive
-\startnewprimitive[title={\prm {glet}}]
+\startnewprimitive[title={\prm {setmathoptions}}]
-This is the global companion of \prm {let}. The fact that it is not an original
-primitive is probably due to the expectation for it not it not being used (as)
-often (as in \CONTEXT).
+This primitive expects a class (number) and a bitset.
+
+\testpage[2]
+
+\startcolumns
+\getbuffer[engine:syntax:classoptioncodes] % weird: one liner at end of page
+\stopcolumns
\stopnewprimitive
-\startnewprimitive[title={\prm {letcsname}}]
+\startnewprimitive[title={\prm {setmathpostpenalty}}]
-It is easy to see that we save two tokens when we use this primitive. As with the
-\type {..defcs..} variants it also saves a push back of the composed macro name.
+This penalty is inserted after an item of a given class but only in inline math
+when text, script or scriptscript style is used, for instance:
\starttyping
-\expandafter\let\csname MyMacro:1\endcsname\relax
- \letcsname MyMacro:1\endcsname\relax
+\setmathpostpenalty 2 250
\stoptyping
\stopnewprimitive
-\startnewprimitive[title={\prm {gletcsname}}]
+\startnewprimitive[title={\prm {setmathprepenalty}}]
-Naturally \LUAMETATEX\ also provides a global variant:
+This penalty is inserted before an item of a given class but only in inline math
+when text, script or scriptscript style is used, for instance:
\starttyping
-\expandafter\global\expandafter\let\csname MyMacro:1\endcsname\relax
-\expandafter \glet\csname MyMacro:1\endcsname\relax
- \gletcsname MyMacro:1\endcsname\relax
+\setmathprepenalty 2 250
\stoptyping
-So, here we save even more.
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {setmathspacing}}]
+
+More details about this feature can be found in \CONTEXT\ but it boils down to
+registering what spacing gets inserted between a pair of classes. It can be
+defined per style or for a set of styles, like:
+
+\starttyping
+\inherited\setmathspacing
+ \mathimplicationcode \mathbinarycode
+ \alldisplaystyles \thickermuskip
+\inherited\setmathspacing
+ \mathradicalcode \mathmiddlecode
+ \allunsplitstyles \pettymuskip
+\stoptyping
+
+Here the \prm {inherited} prefix signals that a change in for instance \prm
+{pettymuskip} is reflected in this spacing pair. In \CONTEXT\ there is a lot of
+granularity with respect to spacing and it took years of experimenting (and
+playing with examples) to get at the current stage. In general users are not
+invited to mess around too much with these values, although changing the bound
+registers (here \prm {pettymuskip} and \type {thickermuskip}) is no problem as it
+consistently makes related spacing pairs follow.
\stopnewprimitive
-\startnewprimitive[title={\prm {cdef}}]
+\startoldprimitive[title={\prm {sfcode}}]
-This primitive is like \prm {edef} but in some usage scenarios is slightly
-more efficient because (delayed) expansion is ignored which in turn saves
-building a temporary token list.
+You can set a space factor on a character. That factor is used when a space
+factor is applied (as part of spacing). It is (mostly) used for adding a
+different space (glue) after punctuation. In some languages different punctuation
+has different factors.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {shapingpenaltiesmode}}]
+
+Shaping penalties are inserted after the lines of a \prm {parshape} and
+accumulate according to this mode, a bitset of:
+
+\getbuffer[engine:syntax:shapingpenaltiescodes]
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {shapingpenalty}}]
+
+In order to prevent a \prm {parshape} to break in unexpected ways we can add a
+dedicated penalty, specified by this parameter.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {shiftedsubprescript}}]
+
+This primitive (or \type {____}) puts a flag on the script but renders
+the same:
\startbuffer
-\edef\FooA{this is foo} \meaningfull\FooA\crlf
-\cdef\FooB{this is foo} \meaningfull\FooB\par
+$
+ x \shiftedsuperprescript{2} \subprescript {2} +
+ x \superprescript {2} \shiftedsubprescript{2} +
+ x \superprescript {2} ____ {2} =
+ x \superprescript {2} \subprescript {2}
+$
\stopbuffer
-\typebuffer {\tttf \getbuffer}
+\typebuffer
+
+Gives: \inlinebuffer.
\stopnewprimitive
-\startnewprimitive[title={\prm {cdefcsname}}]
+\startnewprimitive[title={\prm {shiftedsubscript}}]
-This primitive is like \prm {edefcsame} but in some usage scenarios is slightly
-more efficient because (delayed) expansion is ignored which in turn saves
-building a temporary token list.
+This primitive (or \type {__}) puts a flag on the script but renders
+the same:
\startbuffer
-\edefcsname FooA\endcsname{this is foo} \meaningasis\FooA\crlf
-\cdefcsname FooB\endcsname{this is foo} \meaningasis\FooB\par
+$
+ x \shiftedsuperscript{2} \subscript {2} +
+ x \superscript {2} \shiftedsubscript{2} +
+ x \superscript {2} __ {2} =
+ x \superscript {2} \subscript {2}
+$
\stopbuffer
-\typebuffer {\tttf \getbuffer}
+\typebuffer
+
+Gives: \inlinebuffer.
\stopnewprimitive
-\startnewprimitive[title={\prm {lettonothing}}]
+\startnewprimitive[title={\prm {shiftedsuperprescript}}]
-This one let's a control sequence to nothing. Assuming that \tex {empty}
-is indeed empty, these two lines are equivalent.
+This primitive (or \type {^^^^}) puts a flag on the script but renders
+the same:
+
+\startbuffer
+$
+ x \shiftedsuperprescript{2} \subprescript {2} +
+ x ^^^^ {2} \subprescript {2} +
+ x \superprescript {2} \shiftedsubprescript{2} =
+ x \superprescript {2} \subprescript {2}
+$
+\stopbuffer
+
+\typebuffer
+
+Gives: \inlinebuffer.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {shiftedsuperscript}}]
+
+This primitive (or \type {^^}) puts a flag on the script but renders
+the same:
+
+\startbuffer
+$
+ x \shiftedsuperscript{2} \subscript {2} +
+ x ^^ {2} \subscript {2} +
+ x \superscript {2} \shiftedsubscript{2} =
+ x \superscript {2} \subscript {2}
+$
+\stopbuffer
+
+\typebuffer
+
+Gives: \inlinebuffer.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {shipout}}][obsolete=yes]
+
+Because there is no backend, this is not supposed to be used. As in traditional
+\TEX\ a box is grabbed but instead of it being processed it gets shown and then
+wiped. There is no real benefit of turning it into a callback.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {shortinlinemaththreshold}}]
+
+This parameter determines when an inline formula is considered to be short. This
+criterium is used for for \prm {preshortinlinepenalty} and \prm
+{postshortinlinepenalty}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {shortinlineorphanpenalty}}]
+
+Short formulas at the end of a line are normally not followed by something other
+than punctuation. This penalty will discourage a break before a short inline
+formula. In practice one can set this penalty to e.g. a relatively low 200 to get
+the desired effect.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {show}}]
+
+Prints to the console (and/or log) what the token after
+it represents.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {showbox}}]
+
+The given box register is shown in the log and on te console (depending on \prm
+{tracingonline}. How much is shown depends on \prm {showboxdepth} and \prm
+{showboxbreadth}. In \LUAMETATEX\ we show more detailed information than in the
+other engines; some specific information is provided via callbacks.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {showboxbreadth}}]
+
+This primitives determine how much of a box is shown when asked for or when
+tracing demands it.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {showboxdepth}}]
+
+This primitives determine how deep tracing a box goes into the box. Some boxes,
+like the ones that has the assembled page.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {showcodestack}}]
+
+This inspector is only useful for low level debugging and reports the current
+state of for instance the current catcode table: \typ {\showcodestack \catcode}.
+See \prm {restorecatcodes} for an example.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {showgroups}}]
+
+This primitive reports the group nesting. At this spot we have a not so
+impressive nesting:
\starttyping
-\let \foo\empty
-\lettonothing\oof
+2:3: simple group entered at line 9375:
+1:3: semisimple group: \begingroup
+0:3: bottomlevel
\stoptyping
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {showifs}}]
+
+This primitive will show the conditional stack in the log file or on the console
+(assuming \prm {tracingonline} being non|-|zero). The shown data is different
+from other engines because we have more conditionals and also support a more flat
+nesting model
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {showlists}}]
+
+This shows the currently built list.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {shownodedetails}}]
+
+When set to a positive value more details will be shown of nodes when applicable.
+Values larger than one will also report attributes. What gets shown depends on
+related callbacks being set.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {showstack}}]
+
+This tracer is only useful for low level debugging of macros, for instance when
+you run out of save space or when you encounter a performance hit.
+
+\starttyping
+ test\scratchcounter0 \showstack
+ {test\scratchcounter1 \showstack}
+{{test\scratchcounter1 \showstack}}
+\stoptyping
+
+reports
+
+\starttyping
+1:3: [savestack size 0]
+1:3: [savestack bottom]
+
+2:3: [savestack size 2]
+2:3: [1: restore, level 1, cs \scratchcounter=integer 1]
+2:3: [0: boundary, group 'bottomlevel', boundary 0, attrlist 3600, line 0]
+2:3: [savestack bottom]
+
+3:3: [savestack size 3]
+3:3: [2: restore, level 1, cs \scratchcounter=integer 1]
+3:3: [1: boundary, group 'simple', boundary 0, attrlist 3600, line 12]
+3:3: [0: boundary, group 'bottomlevel', boundary 0, attrlist 3600, line 0]
+3:3: [savestack bottom]
+\stoptyping
+
+while
+
+\starttyping
+ test\scratchcounter1 \showstack
+ {test\scratchcounter1 \showstack}
+{{test\scratchcounter1 \showstack}}
+\stoptyping
+
+shows this:
+
+\starttyping
+1:3: [savestack size 0]
+1:3: [savestack bottom]
+
+2:3: [savestack size 1]
+2:3: [0: boundary, group 'bottomlevel', boundary 0, attrlist 3600, line 0]
+2:3: [savestack bottom]
+
+3:3: [savestack size 2]
+3:3: [1: boundary, group 'simple', boundary 0, attrlist 3600, line 16]
+3:3: [0: boundary, group 'bottomlevel', boundary 0, attrlist 3600, line 0]
+3:3: [savestack bottom]
+\stoptyping
+
+Because in the second example the value of \type {\scratchcounter} doesn't really
+change inside the group there is no need for a restore entry on the stack. In
+\LUAMETATEX\ there are checks for that so that we consume less stack space. We
+also store some states (like the line number and current attribute list pointer)
+in a stack boundary.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {showthe}}]
+
+Prints to the console (and/or log) the value of token after it.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {showtokens}}]
+
+This command expects a (balanced) token list, like
+
+\starttyping
+\showtokens{a few tokens}
+\stoptyping
+
+Depending on what you want to see you need to expand:
+
+\starttyping
+\showtokens\expandafter{\the\everypar}
+\stoptyping
+
+which is equivalent to \typ {\showthe \everypar}. It is an \ETEX\ extension.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {singlelinepenalty}}]
+
+This is a penalty that gets injected before a paragraph that has only one line.
+It is a one|-|shot parameter, so like \prm {looseness} it only applies to the
+upcoming (or current) paragraph.
+
\stopnewprimitive
-\startnewprimitive[title={\prm {glettonothing}}]
+\startoldprimitive[title={\prm {skewchar}}][obsolete=yes]
-This is the global companion of \prm {lettonothing}.
+This is an (imaginary) character that is used in math fonts. The kerning pair
+between this character and the current one determines the top anchor of a
+possible accent. In \OPENTYPE\ there is a dedicated character property for this
+(but for some reason not for the bottom anchor).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {skip}}]
+
+This is the accessor for an indexed skip (glue) register.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {skipdef}}]
+
+This command associates a control sequence with a skip register (accessed by number).
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {snapshotpar}}]
+
+There are many parameters involved in typesetting a paragraph. One complication
+is that parameters set in the middle might have unpredictable consequences due to
+grouping, think of:
+
+\starttyping
+text text <some setting> text text \par
+text {text <some setting> text } text \par
+\stoptyping
+
+This makes in traditional \TEX\ because there is no state related to the current
+paragraph. But in \LUATEX\ we have the initial so called par node that remembers
+the direction as well as local boxes. In \LUAMETATEX\ we store way more when this
+node is created. That means that later settings no longer replace the stored ones.
+
+The \prm {snapshotpar} takes a bitset that determine what stored parameters get
+updated to the current values.
+
+\startcolumns[n=3]
+\getbuffer[engine:syntax:frozenparcodes]
+\stopcolumns
+
+One such value covers multiple values, so for instance \type {skip} is good for
+storing the current \prm {leftskip} and \prm {rightskip} values. More about this
+feature can be found in the \CONTEXT\ documentation.
+
+The list of parameters that gets reset after a paragraph is longer than for
+\PDFTEX\ and \LUAMETATEX: \prm {emergencyleftskip}, \prm {emergencyrightskip}, \prm
+{hangafter}, \prm {hangindent}, \prm {interlinepenalties}, \prm
+{localbrokenpenalty}, \prm {localinterlinepenalty}, \prm {localpretolerance},
+\prm {localtolerance}, \prm {looseness}, \prm {parshape} and \prm
+{singlelinepenalty}.
\stopnewprimitive
-\startnewprimitive[title={\prm {norelax}}]
+\startoldprimitive[title={\prm {spacefactor}}]
-The rationale for this command can be shown by a few examples:
+The space factor is a somewhat complex feature. When during scanning a character
+is appended that has a \prm {sfcode} other than 1000, that value is saved. When
+the time comes to insert a space triggered glue, and that factor is 2000 or more,
+and when \prm {xspaceskip} is nonzero, that value is used and we're done.
+
+If these criteria are not met, and \prm {spaceskip} is nonzero, that value is
+used, otherwise the space value from the font is used. Now, it if the space factor
+is larger than 2000 the extra space value from the font is added to the set value.
+Next the engine is going to tweak the stretch and shrink if that value and in
+\LUAMETATEX\ that can be done in different ways, depending on \prm {spacefactormode},
+\prm {spacefactorstretchlimit} and \prm {spacefactorshrinklimit}.
+
+First the stretch. When the set limit is 1000 or more and the saved space factor
+is also 1000 or more, we multiply the stretch by the limit, otherwise the saved
+space factor is used.
+
+Shrink is done differently. When the shrink limit and space factor are both 1000
+or more, we will scale the shrink component by the limit, otherwise we multiply
+by the saved space factor but here we have three variants, determined by the
+value of \prm {spacefactormode}.
+
+In the first case, when the limit kicks in, a mode value~1 will multiply by limit
+and divides by 1000. A value of~2 multiplies by 2000 and divides by the limit.
+Other mode values multiply by 1000 and divide by the limit. When the limit is not
+used, the same happens but with the saved space factor.
+
+If this sounds complicated, here is what regular \TEX\ does: stretch is
+multiplied by the factor and divided by 1000 while shrink is multiplied by 1000
+and divided by the saved factor. The (new) mode driven alternatives are the
+result of extensive experiments done in the perspective of enhancing the
+rendering of inline math as well as additional par builder passes. For sure
+alternative strategies are possible and we can always add more modes.
+
+A better explanation of the default strategy around spaces can be found in (of
+course) The \TEX book and \TEX\ by Topic.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {spacefactormode}}]
+
+Its setting determines the way the glue components (currently only shrink) adapts
+itself to the current space factor (determined by by the character preceding a
+space).
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {spacefactorshrinklimit}}]
+
+This limit is used when \prm {spacefactormode} is set. See \prm {spacefactor} for a
+bit more explanation.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {spacefactorstretchlimit}}]
+
+This limit is used when \prm {spacefactormode} is set. See \prm {spacefactor} for a
+bit more explanation.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {spaceskip}}]
+
+Normally the glue inserted when a space is encountered is taken from the font but
+this parameter can overrule that.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {span}}]
+
+This primitive combined two upcoming cells into one. Often it is used in
+combination with \prm {omit}. However, in the preamble it forces the next token
+to be expanded, which means that nested \prm {tabskips} and align content markers
+are seen.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {splitbotmark}}][obsolete=yes]
+
+This is a reference to the last mark on the currently split off box, it gives
+back tokens.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {splitbotmarks}}]
+
+This is a reference to the last mark with the given id (a number) on the
+currently split off box, it gives back tokens.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {splitdiscards}}]
+
+When a box is split off, items like glue are discarded. This internal register
+keeps the that list so that it can be pushed back if needed.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {splitfirstmark}}][obsolete=yes]
+
+This is a reference to the first mark on the currently split off box, it gives
+back tokens.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {splitfirstmarks}}]
+
+This is a reference to the first mark with the given id (a number) on the
+currently split off box, it gives back tokens.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {splitmaxdepth}}]
+
+The depth of the box that results from a \prm {vsplit}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {splittopskip}}]
+
+This is the amount of glue that is added to the top of a (new) split of part of a
+box when \prm {vsplit} is applied.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {srule}}]
+
+This inserts a rule with no width. When a \type {font} and a \type {char} are
+given the height and depth of that character are taken. Instead of a font \type
+{fam} is also accepted so that we can use it in math mode.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {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={\prm {subprescript}}]
+
+Instead of three or four characters with catcode \the\subscriptcatcode\ (\type
+{__} or \type {____}) this primitive can be used. It will add the following
+argument as lower left script to the nucleus.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {subscript}}]
+
+Instead of one or two characters with catcode \the\superscriptcatcode\ (\type {_}
+or \type {__}) this primitive can be used. It will add the following argument as
+upper left script to the nucleus.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {superprescript}}]
+
+Instead of three or four characters with catcode \the\superscriptcatcode\ (\type
+{^^^} or \type {^^^^}) this primitive can be used. It will add the following
+argument as upper left script to the nucleus.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {superscript}}]
+
+Instead of one or two character with catcode \the\superscriptcatcode\ (\type {^}
+or \type {^^})this primitive can be used. It will add the following argument as
+upper right script to the nucleus.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {supmarkmode}}]
+
+As in other languages, \TEX\ has ways to escape characters and get whatever
+character needed into the input. By default multiple \type {^} are used for this.
+The dual \type {^^} variant is a bit weird as it is not continuous but \type
+{^^^^} and \type {^^^^^^} provide four or six byte hexadecimal references ot
+characters. The single \type {^} is also used for superscripts but because we
+support prescripts and indices we get into conflicts with the escapes.
+
+When this internal quantity is set to zero, multiple \type {^}'s are interpreted
+in the input and produce characters. Other values disable the multiple parsing in
+text and|/|or math mode:
\startbuffer
-\dimen0 1pt \dimen2 1pt \dimen4 2pt
-\edef\testa{\ifdim\dimen0=\dimen2\norelax N\else Y\fi}
-\edef\testb{\ifdim\dimen0=\dimen2\relax N\else Y\fi}
-\edef\testc{\ifdim\dimen0=\dimen4\norelax N\else Y\fi}
-\edef\testd{\ifdim\dimen0=\dimen4\relax N\else Y\fi}
-\edef\teste{\norelax}
+\normalsupmarkmode0 $ X^58 \quad X^^58 $ ^^58
+\normalsupmarkmode1 $ X^58 \quad X^^58 $ ^^58
+\normalsupmarkmode2 $ X^58 \quad X^^58 $ % ^^58 : error
\stopbuffer
\typebuffer
-The five meanings are:
+In \CONTEXT\ we default to one but also have the \prm {catcode} set to \the
+\catcode`^ and the \prm {amcode} to \the \amcode `^.
-\start \getbuffer \starttabulate[|T|T|]
-\NC \string\testa \NC \meaning\testa \NC \NR
-\NC \string\testb \NC \meaning\testb \NC \NR
-\NC \string\testc \NC \meaning\testc \NC \NR
-\NC \string\testd \NC \meaning\testd \NC \NR
-\NC \string\teste \NC \meaning\teste \NC \NR
-\stoptabulate \stop
-
-So, the \prm {norelax} acts like \prm {relax} but is not pushed back as
-usual (in some cases).
+\startlines
+\catcode`^=\superscriptcatcode % to make sure we handle it in math
+\amcode `^=\superscriptcatcode
+\getbuffer
+\stoplines
\stopnewprimitive
@@ -2852,164 +11294,694 @@ an experimental feature.
\stopnewprimitive
-\startnewprimitive[title={\prm {integerdef}}]
+\startnewprimitive[title={\prm {tabsize}}]
-You can alias to a count (integer) register with \prm {countdef}:
+This primitive can be used in the preamble of an alignment and sets the size of
+a column, as in:
+
+\startbuffer
+\halign{%
+ \aligncontent \aligntab
+ \aligncontent\tabsize 3cm \aligntab
+ \aligncontent \aligntab
+ \aligncontent\tabsize 0cm \cr
+ 1 \aligntab 111\aligntab 1111\aligntab 11\cr
+ 222\aligntab 2 \aligntab 2222\aligntab 22\cr
+}
+\stopbuffer
+
+\typebuffer
+
+As with \prm {tabskip} you need to reset the value explicitly, so that is why we
+get two wide columns:
+
+\blank {\showboxes \getbuffer} \blank
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {tabskip}}]
+
+This traditional primitive can be used in the preamble of an alignment and sets the
+space added between columns, for example:
+
+\startbuffer
+\halign{%
+ \aligncontent \aligntab
+ \aligncontent\tabskip 3cm \aligntab
+ \aligncontent \aligntab
+ \aligncontent\tabskip 0cm \cr
+ 1 \aligntab 111\aligntab 1111\aligntab 11\cr
+ 222\aligntab 2 \aligntab 2222\aligntab 22\cr
+}
+\stopbuffer
+
+\typebuffer
+
+You need to reset the skip explicitly, which is why we get it applied twice here:
+
+\blank {\showboxes \getbuffer} \blank
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {textdirection}}]
+
+This set the text direction to \type {l2r} (0) or \type {r2l} (1). It also
+triggers additional checking for balanced flipping in node lists.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {textfont}}]
+
+This primitive is like \prm {font} but with a family number as (first) argument
+so it is specific for math. It is the largest one of the three family members; its
+relatives are \prm {scriptfont} and \prm {scriptscriptfont}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {textstyle}}]
+
+One of the main math styles; integer representation: \the\textstyle.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {the}}]
+
+The \prm {the} primitive serializes the following token, when applicable:
+integers, dimensions, token registers, special quantities, etc. The catcodes of
+the result will be according to the current settings, so in \type {\the \dimen0},
+the \type {pt} will have catcode \quote {letter} and the number and period will
+become \quote {other}.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {thewithoutunit}}]
+
+The \prm{the} primitive, when applied to a dimension variable, adds a \type {pt}
+unit. because dimensions are the only traditional unit with a fractional part
+they are sometimes used as pseudo floats in which case \prm {thewithoutunit} can
+be used to avoid the unit. This is more convenient than stripping it off
+afterwards (via an expandable macro).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {thickmuskip}}]
+
+A predefined mu skip register that can be used in math (inter atom) spacing. The
+current value is {\tt \the\thickmuskip}. In traditional \TEX\ most inter atom
+spacing is hard coded using the predefined registers.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {thinmuskip}}]
+
+A predefined mu skip register that can be used in math (inter atom) spacing. The
+current value is {\tt \the\thinmuskip}. In traditional \TEX\ most inter atom
+spacing is hard coded using the predefined registers.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {time}}]
+
+This internal number starts out with minute (starting at midnight) that the job
+started.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tinymuskip}}]
+
+A predefined mu skip register that can be used in math (inter atom) spacing. The
+current value is {\tt \the\tinymuskip}. This one complements \prm {thinmuskip},
+\prm {medmuskip}, \prm {thickmuskip} and the new \prm {pettymuskip}
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {tocharacter}}]
+
+The given number is converted into an \UTF-8 sequence. In \LUATEX\ this one is
+named \type {\Uchar}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {todimension}}]
+
+\startbuffer
+\scratchdimen = 1234pt \todimension\scratchdimen
+\stopbuffer
+
+The following code gives this: {\nospacing\inlinebuffer} and like its numeric
+counterparts accepts anything that resembles a number this one goes beyond
+(user, internal or pseudo) registers values too.
+
+\typebuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {tohexadecimal}}]
+
+\startbuffer
+\scratchcounter = 1234 \tohexadecimal\scratchcounter
+\stopbuffer
+
+The following code gives this: {\nospacing\inlinebuffer} with uppercase letters.
+
+\typebuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {tointeger}}]
+
+\startbuffer
+\scratchcounter = 1234 \tointeger\scratchcounter
+\stopbuffer
+
+The following code gives this: {\nospacing\inlinebuffer} and is equivalent to
+\prm {number}.
+
+\typebuffer
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {tokenized}}]
+
+Just as \prm {expanded} has a counterpart \prm {unexpanded}, it makes sense to give
+\prm {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 {\tttf \getbuffer}
+
+This primitive is similar to:
\starttyping
-\countdef\MyCount134
+\def\tokenized#1{\scantextokens\expandafter{\normalexpanded{#1}}}
\stoptyping
-Afterwards the next two are equivalent:
+and should be more efficient, not that it matters much as we don't use it that
+much (if at all).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {toks}}]
+
+This is the accessor of a token register so it expects a number or \prm
+{toksdef}'d macro.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {toksapp}}]
+
+One way to append something to a token list is the following:
\starttyping
-\MyCount = 99
-\count1234 = 99
+\scratchtoks\expandafter{\the\scratchtoks more stuff}
\stoptyping
-where \type {\MyCount} can be a bit more efficient because no index needs to be
-scanned. However, in terms of storage the value (here 99) is always in the register
-so \type {\MyCount} has to get there. This indirectness has the benefit that directly
-setting the value is reflected in the indirect accessor.
+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
-\integerdef\MyCount = 99
+\toksapp\scratchtoks{more stuff}
+\toksapp\scratchtoksone\scratchtokstwo
\stoptyping
-This primitive also defines a numeric equivalent but this time the number is stored
-with the equivalent. This means that:
+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
+
+\startoldprimitive[title={\prm {toksdef}}]
+
+The given name (control sequence) will be bound to the given token register (a
+number). Often this primitive is hidden in a high level macro that manages
+allocation.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tokspre}}]
+
+Where appending something is easy because of the possible \prm {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
-\let\MyCopyOfCount = \MyCount
+\tokspre\scratchtoks{less stuff}
+\tokspre\scratchtoksone\scratchtokstwo
\stoptyping
-will store the {\em current} value of \type {\MyCount} in \type {\MyCopyOfCount} and
-changing either of them is not reflected in the other.
+This prepends the token list that is provided.
-The usual \prm {advance}, \prm {multiply} and \prm {divide} can be used with these
-integers and they behave like any number. But compared to registers they are actually
-more a constant.
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {tolerance}}]
+
+When the par builder runs into a line with a badness larger than this value and
+when \prm {emergencystretch} is set a third pass is enabled. In \LUAMETATEX\ we
+can have more than one second pass and there are more parameters that influence
+the process.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tolerant}}]
+
+This prefix tags the following macro as being tolerant with respect to the
+expected arguments. It only makes sense when delimited arguments are used or when
+braces are mandate.
+
+\startbuffer
+\tolerant\def\foo[#1]#*[#2]{(#1)(#2)}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This definition makes \type {\foo} tolerant for various calls:
+
+\startbuffer
+\foo \foo[1] \foo [1] \foo[1] [2] \foo [1] [2]
+\stopbuffer
+
+\typebuffer
+
+these give: \inlinebuffer. The spaces after the first call disappear because the
+macro name parser gobbles it, while in the second case the \type {#*} gobbles
+them. Here is a variant:
+
+\startbuffer
+\tolerant\def\foo[#1]#,[#2]{!#1!#2!}
+
+\foo[?] x
+\foo[?] [?] x
+
+\tolerant\def\foo[#1]#*[#2]{!#1!#2!}
+
+\foo[?] x
+\foo[?] [?] x
+\stopbuffer
+
+\typebuffer
+
+We now get the following:
+
+\getbuffer
+
+Here the \type {#,} remembers that spaces were gobbles and they will be put back
+when there is no further match. These are just a few examples of this tolerant
+feature. More details can be found in the lowlevel manuals.
\stopnewprimitive
-\startnewprimitive[title={\prm {dimensiondef}}]
+\startnewprimitive[title={\prm {tomathstyle}}]
-A variant of \prm {integerdef} is:
+Internally math styles are numbers, where \prm {displaystyle} is \tomathstyle
+\displaystyle \space and \prm {crampedscriptscriptstyle} is \tomathstyle
+\crampedscriptscriptstyle. You can convert the verbose style to a number with
+\prm {tomathstyle}.
-\starttyping
-\dimensiondef\MyDimen = 1234pt
-\stoptyping
+\stopnewprimitive
-The properties are comparable to the ones described in the section \prm
-{integerdef}.
+\startoldprimitive[title={\prm {topmark}}][obsolete=yes]
+
+This is a reference to the last mark on the previous (split off) page, it gives
+back tokens.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {topmarks}}]
+
+This is a reference to the last mark with the given id (a number) on the previous
+page, it gives back tokens.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {topskip}}]
+
+This is the amount of glue that is added to the top of a (new) page.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {toscaled}}]
+
+\startbuffer
+\scratchdimen = 1234pt \toscaled\scratchdimen
+\stopbuffer
+
+The following code gives this: {\nospacing\inlinebuffer} is similar to \prm
+{todimension} but omits the \type {pt} so that we don't need to revert to some
+nasty stripping code.
+
+\typebuffer
\stopnewprimitive
-\startnewprimitive[title={\prm {gluespecdef}}]
+\startnewprimitive[title={\prm {tosparsedimension}}]
-A variant of \prm {integerdef} and \prm {dimensiondef} is:
+\startbuffer
+\scratchdimen = 1234pt \tosparsedimension\scratchdimen
+\stopbuffer
-\starttyping
-\gluespecdef\MyGlue = 3pt plus 2pt minus 1pt
-\stoptyping
+The following code gives this: {\nospacing\inlinebuffer} where \quote {sparse}
+indicates that redundant trailing zeros are not shown.
-The properties are comparable to the ones described in the previous sections.
+\typebuffer
\stopnewprimitive
-\startnewprimitive[title={\prm {mugluespecdef}}]
+\startnewprimitive[title={\prm {tosparsescaled}}]
-A variant of \prm {gluespecdef} that expects \type {mu} units is:
+\startbuffer
+\scratchdimen = 1234pt \tosparsescaled\scratchdimen
+\stopbuffer
-\starttyping
-\mugluespecdef\MyGlue = 3mu plus 2mu minus 1mu
-\stoptyping
+The following code gives this: {\nospacing\inlinebuffer} where \quote {sparse}
+means that redundant trailing zeros are omitted.
-The properties are comparable to the ones described in the previous sections.
+\typebuffer
\stopnewprimitive
-\startnewprimitive[title={\prm {advanceby}}]
+\startnewprimitive[title={\prm {tpack}}]
-This is slightly more efficient variant of \prm {advance} that doesn't look for
-\type {by} and therefore, if one is missing, doesn't need to push back the last
-seen token. Using \prm {advance} with \type {by} is nearly as efficient but takes
-more tokens.
+This primitive is like \prm {vtop} but without the callback overhead.
\stopnewprimitive
-\startnewprimitive[title={\prm {multiplyby}}]
+\startnewprimitive[title={\prm {tracingadjusts}}]
-This is slightly more efficient variant of \prm {multiply} that doesn't look for
-\type {by}. See previous section.
+In \LUAMETATEX\ the adjust feature has more functionality and also is carried
+over. When set to a positive values \prm {vadjust} processing reports details.
+The higher the number, the more you'll get.
\stopnewprimitive
-\startnewprimitive[title={\prm {divideby}}]
+\startnewprimitive[title={\prm {tracingalignments}}]
-This is slightly more efficient variant of \prm {divide} that doesn't look for
-\type {by}. See previous section.
+When set to a positive value the alignment mechanism will keep you informed about
+what is done in various stages. Higher values unleash more information, including
+what callbacks kick in.
\stopnewprimitive
-\startnewprimitive[title={\prm {localcontrolledloop}}]
+\startoldprimitive[title={\prm {tracingassigns}}]
-As with more of the primitives discussed here, there is a manual in the \quote
-{lowlevel} subset that goes into more detail. So, here a simple example has to
-do:
+When set to a positive values assignments to parameters and variables are
+reported on the console and|/|or in the log file. Because \LUAMETATEX\ avoids
+redundant assignments these don't get reported.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {tracingcommands}}]
+
+When set to a positive values the commands (primitives) are reported on the console
+and|/|or in the log file.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tracingexpressions}}]
+
+The extended expression commands like \prm {numexpression} and \prm
+{dimexpression} can be traced by setting this parameter to a positive value.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {tracingfullboxes}}]
+
+When set to a positive value the box will be shown in case of an overfull box.
+When a quality callback is set this will not happen as all reporting is then
+delegated.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {tracinggroups}}]
+
+When set to a positive values grouping is reported on the console and|/|or in the
+log file.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tracinghyphenation}}]
+
+When set to a positive values the hyphenation process is reported on the console
+and|/|or in the log file.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {tracingifs}}]
+
+When set some details of what gets tested and what results are seen is reported.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tracinginserts}}]
+
+A positive value enables tracing where values larger than~1 will report more
+details.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {tracinglevels}}]
+
+The lines in a log file can be prefixed with some details, depending on the bits
+set:
+
+\starttabulate[|T|l|]
+\NC 0x1 \NC current group \NC \NR
+\NC 0x2 \NC current input \NC \NR
+\NC 0x4 \NC catcode table \NC \NR
+\stoptabulate
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {tracinglists}}]
+
+At various stages the lists being processed can be shown. This is mostly an
+option for developers.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {tracinglostchars}}]
+
+When set to one characters not present in a font will be reported in the log
+file, a value of two will also report this on the console.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {tracingmacros}}]
+
+This parameter controls reporting of what macros are seen and expanded.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tracingmarks}}]
+
+Marks are information blobs that track states that can be queried when a page is
+handled over to the shipout routine. They travel through the system in a bit
+different than traditionally: like like adjusts and inserts deeply buried ones
+bubble up to outer level boxes. This parameters controls what progress gets
+reported.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {tracingmath}}]
+
+The higher the value, the more information you will get about the various stages
+in rendering math. Because tracing of nodes is rather verbose you need to know a
+bit what this engine does. Conceptually there are differences between the
+\LUAMETATEX\ and traditional engine, like more passes, inter-atom spacing,
+different low level mechanisms. This feature is mostly meant for developers who
+tweak the many available parameters.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {tracingnesting}}]
+
+A positive value triggers log messages about the current level.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tracingnodes}}]
+
+When set to a positive value more details about nodes (in boxes) will be
+reported. Because this is also controlled by callbacks what gets reported is
+macro package dependent.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {tracingonline}}]
+
+The engine has two output channels: the log file and the console and by default
+most tracing (when enabled) goes to the log file. When this parameter is set to a
+positive value tracing will also happen in the console. Messages from the \LUA\
+end can be channeled independently.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {tracingoutput}}]
+
+Values larger than one result in some information about what gets passed to the
+output routine.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {tracingpages}}]
+
+Values larger than one result in some information about the page building
+process. In \LUAMETATEX\ there is more info for higher values.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {tracingparagraphs}}]
+
+Values larger than one result in some information about the par building process.
+In \LUAMETATEX\ there is more info for higher values.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tracingpasses}}]
+
+In \LUAMETATEX\ you can configure additional second stage par builder passes and
+this parameter controls what gets reported on the console and|/|or in the log
+file.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {tracingpenalties}}]
+
+This setting triggers reporting of actions due to special penalties in the
+page builder.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {tracingrestores}}]
+
+When set to a positive values (re)assignments after grouping to parameters and
+variables are reported on the console and|/|or in the log file. Because
+\LUAMETATEX\ avoids redundant assignments these don't get reported.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {tracingstats}}]
+
+This parameter is a dummy in \LUAMETATEX. There are anyway some statistic
+reported when the format is made but for a regular run it is up to the macro
+package to come up with useful information.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {tsplit}}]
+
+This splits like \prm {vsplit} but it returns a \prm {vtop} box instead.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {uccode}}]
+
+When the \prm {uppercase} operation is applied the uppercase code of a character
+is used for the replacement. This primitive is used to set that code, so it
+expects two character number.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {uchyph}}]
+
+When set to a positive number words that start with a capital will be hyphenated.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {uleaders}}]
+
+This leader adapts itself after a paragraph has been typeset. Here are a few
+examples:
\startbuffer
-\localcontrolledloop 1 100 1 {%
- \ifnum\currentloopiterator>6\relax
- \quitloop
- \else
- [\number\currentloopnesting:\number\currentloopiterator]
- \localcontrolledloop 1 8 1 {%
- (\number\currentloopnesting:\number\currentloopiterator)
- }\par
- \fi
-}
+test \leaders \hbox {x}\hfill\ test
+test \uleaders \hbox{x x x x}\hfill\ test
+test \hbox{x x x x}\hskip 3cm plus 1cm\ test
+test \uleaders \hbox{x x x x}\hskip 3cm plus 1cm\ test
\stopbuffer
\typebuffer
-Here we see the main loop primitive being used nested. The code shows how we can
-\prm {quitloop} and have access to the \prm {currentloopiterator} as well as the
-nesting depth \prm {currentloopnesting}.
+When an \prm {uleaders} is used the glue in the given box will be adapted to the
+available space.
-\startpacked \getbuffer \stoppacked
+\startlines \getbuffer \stoplines
-Be aware of the fact that \prm {quitloop} will end the loop at the {\em next}
-iteration so any content after it will show up. Normally this one will be issued
-in a condition and we want to end that properly. Also keep in mind that because
-we use local control (a nested \TEX\ expansion loop) anything you feed back can
-be injected out of order.
+\startsetups adaptive:test
+ \setbox\usedadaptivebox\hbox to \usedadaptivewidth yoffset -\usedadaptivedepth \bgroup
+ \externalfigure
+ [cow.pdf]
+ [width=\usedadaptivewidth,
+ height=\dimexpr\usedadaptiveheight+\usedadaptivedepth\relax]%
+ \egroup
+\stopsetups
-The three numbers can be separated by an equal sign which is a trick to avoid
-look ahead issues that can result from multiple serialized numbers without spaces
-that indicate the end of sequence of digits.
+Optionally the \type {callback} followed by a number can be given, in which case
+a callback kicks in that gets that the node, a group identifier, and the number
+passed. It permits (for instance) adaptive graphics: \dostepwiserecurse {1} {100} {5}
+{\hbox {#1=\romannumerals{#1}} {\adaptivebox [strut=yes, setups=adaptive:test]{}} }.
\stopnewprimitive
-\startnewprimitive[title={\prm {expandedloop}}]
+\startoldprimitive[title={\prm {unboundary}}]
-This variant of the previously introduced \prm {localcontrolledloop} doesn't
-enter a local branch but immediately does its work. This means that it can be
-used inside an expansion context like \prm {edef}.
+When possible a preceding boundary node will be removed.
-\startbuffer
-\edef\whatever
- {\expandedloop 1 10 1
- {\scratchcounter=\the\currentloopiterator\relax}}
+\stopoldprimitive
-\meaningasis\whatever
+\startnewprimitive[title={\prm {undent}}]
+
+When possible the already added indentation will be removed.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {underline}}]
+
+This is a math specific primitive that draws a line under the given content. It
+is a poor mans replacement for a delimiter. The thickness is set with \prm
+{Umathunderbarrule}, the distance between content and rule is set by \prm
+{Umathunderbarvgap} and \prm {Umathunderbarkern} is added above the rule. The
+style used for the content under the rule can be set with \prm
+{Umathunderlinevariant}. See \prm {overline} for what these parameters do.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {unexpanded}}]
+
+This is an \ETEX\ enhancement. The content will not be expanded in a context
+where expansion is happening, like in an \prm {edef}. In \CONTEXT\ you need to
+use \prm {normalunexpanded} because we already had a macro with that name.
+
+\startbuffer
+\def \A{!} \meaning\A
+\def \B{?} \meaning\B
+\edef\C{\A\B} \meaning\C
+\edef\C{\normalunexpanded{\A}\B} \meaning\C
\stopbuffer
\typebuffer
-\start \veryraggedright \tt\tfx \getbuffer \stop \blank
+\startlines \tttf \getbuffer \stoplines
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {unexpandedendless}}]
-The next section shows a companion primitive.
+This one loops forever so you need to quit explicitly.
\stopnewprimitive
@@ -3059,6 +12031,430 @@ that's what deep down empty boils down to.
\stopnewprimitive
+\startnewprimitive[title={\prm {unexpandedrepeat}}]
+
+This one takes one instead of three arguments which looks better in simple loops.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {unhbox}}]
+
+A box is a packaged list and once packed travels through the system as a single
+object with properties, like dimensions. This primitive injects the original list
+and discards the wrapper.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {unhcopy}}]
+
+This is like \prm {unhbox} but keeps the original. It is one of the more costly
+operations.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {unhpack}}]
+
+This primitive is like \prm {unhbox} but without the callback overhead.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {unkern}}]
+
+This removes the last kern, if possible.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {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={\prm {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={\prm {unletprotected}}]
+
+The complementary operation of \prm {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\par
+\stopbuffer
+
+\typebuffer
+
+Compare this with the example in the previous section:
+
+{\tttf \getbuffer}
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {unpenalty}}]
+
+This removes the last penalty, if possible.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {unskip}}]
+
+This removes the last glue, if possible.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {untraced}}]
+
+Related to the meaning providers is the \prm {untraced} prefix. It marks a macro
+as to be reported by name only. It makes the macro look like a primitive.
+
+\starttyping
+ \def\foo{}
+\untraced\def\oof{}
+
+\scratchtoks{\foo\foo\oof\oof}
+
+\tracingall \the\scratchtoks \tracingnone
+\stoptyping
+
+This will show up in the log as follows:
+
+\starttyping
+1:4: {\the}
+1:5: \foo ->
+1:5: \foo ->
+1:5: \oof
+1:5: \oof
+\stoptyping
+
+This is again a trick to avoid too much clutter in a log. Often it doesn't matter
+to users what the meaning of a macro is (if they trace at all). \footnote {An
+earlier variant could also hide the expansion completely but that was just
+confusing.}
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {unvbox}}]
+
+A box is a packaged list and once packed travels through the system as a single
+object with properties, like dimensions. This primitive injects the original list
+and discards the wrapper.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {unvcopy}}]
+
+This is like \prm {unvbox} but keeps the original. It is one of the more costly
+operations.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {unvpack}}]
+
+This primitive is like \prm {unvbox} but without the callback overhead.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {uppercase}}]
+
+See its counterpart \prm {lowercase} for an explanation.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vadjust}}]
+
+This injects a node that stores material that will injected before or after the
+line where it has become part of. In \LUAMETATEX\ there are more features, driven
+by keywords.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {valign}}]
+
+This command starts vertically aligned material. Its counterpart \prm {halign} is
+used more frequently. Most macro packages provide wrappers around these commands.
+First one specifies a preamble which is then followed by entries (rows and
+columns).
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {variablefam}}]
+
+In traditional \TEX\ sets the family of what are considered variables (class 7)
+to the current family (which often means that they adapt to the current alphabet)
+and then injects a math character of class ordinary. This parameter can be used
+to obey the given class when the family set for a character is the same as this
+parameter. So we then use the given class with the current family. It is mostly
+there for compatibility with \LUATEX\ and experimenting (outside \CONTEXT).
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {vbadness}}]
+
+This sets the threshold for reporting a (vertical) badness value, its current
+value is \the \badness.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vbox}}]
+
+This creates a vertical box. In the process callbacks can be triggered that can
+preprocess the content, influence line breaking as well as assembling the
+resulting paragraph. More can be found in dedicated manuals. The baseline is
+at the bottom.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vcenter}}]
+
+In traditional \TEX\ this box packer is only permitted in math mode but in
+\LUAMETATEX\ it also works in text mode. The content is centered in the vertical
+box.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vfil}}]
+
+This is a shortcut for \typ {\vskip plus 1 fil} (first order filler).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vfill}}]
+
+This is a shortcut for \typ {\vskip plus 1 fill} (second order filler).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vfilneg}}]
+
+This is a shortcut for \typ {\vskip plus - 1 fil} so it can compensate \prm
+{vfil}.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vfuzz}}]
+
+This dimension sets the threshold for reporting vertical boxes that are under- or
+overfull. The current value is \the \vfuzz.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {virtualhrule}}]
+
+This is a horizontal rule with zero dimensions from the perspective of the
+frontend but the backend can access them as set.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {virtualvrule}}]
+
+This is a vertical rule with zero dimensions from the perspective of the frontend
+but the backend can access them as set.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {vkern}}]
+
+This primitive is like \prm {kern} but will force the engine into vertical mode
+if it isn't yet.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {vpack}}]
+
+This primitive is like \prm {vbox} but without the callback overhead.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {vpenalty}}]
+
+This primitive is like \prm {penalty} but will force the engine into vertical
+mode if it isn't yet.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {vrule}}]
+
+This creates a vertical rule. Unless the height and depth are set they will
+stretch to fix the available space. In addition to the traditional \type {width},
+\type {height} and \type {depth} specifiers some more are accepted. These are
+discussed in other manuals. See \prm {hrule} for a simple example.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vsize}}]
+
+This sets (or gets) the current vertical size. While setting the \prm {hsize}
+inside a \prm {vbox} has consequences, setting the \prm {vsize} mostly makes
+sense at the outer level (the page).
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vskip}}]
+
+The given glue is injected in the vertical list. If possible vertical mode is
+entered.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vsplit}}]
+
+This operator splits a given amount from a vertical box. In \LUAMETATEX\ we can
+split \type {to} but also \type {upto}, so that we don't have to repack the
+result in order to see how much is actually in there.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vss}}]
+
+This is the vertical variant of \prm {hss}. See there for what it means.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {vtop}}]
+
+This creates a vertical box. In the process callbacks can be triggered that can
+preprocess the content, influence line breaking as well as assembling the
+resulting paragraph. More can be found in dedicated manuals. The baseline is
+at the top.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {wd}}]
+
+Returns the width of the given box.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {widowpenalties}}]
+
+This is an array of penalty put before the last lines in a paragraph. High values
+discourage (or even prevent) a lone line at the beginning of a next page. This
+command expects a count value indicating the number of entries that will follow.
+The first entry is ends up before the last line.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {widowpenalty}}]
+
+This is the penalty put before a widow line in a paragraph. High values
+discourage (or even prevent) a lone line at the beginning of a next page.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {wordboundary}}]
+
+The hypenation routine has to decide where a word begins and ends. If you want to
+make sure that there is a proper begin or end of a word you can inject this
+boundary.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {wrapuppar}}]
+
+What this primitive does can best be shown with an example:
+
+\startbuffer
+some text\wrapuppar{one} and some\wrapuppar{two} more
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\blank \getbuffer \blank
+
+So, it is a complementary command to \prm {everypar}. It can only be issued
+inside a paragraph.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {xdef}}]
+
+This is an alternative for \type {\global \edef}:
+
+\starttyping
+\xdef\MyMacro{...}
+\stoptyping
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {xdefcsname}}]
+
+This is the companion of \prm {xdef}:
+
+\starttyping
+\expandafter\xdef\csname MyMacro:1\endcsname{...}
+ \xdefcsname MyMacro:1\endcsname{...}
+\stoptyping
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {xleaders}}]
+
+See \prm {gleaders} for an explanation.
+
+\stopoldprimitive
+
+\startoldprimitive[title={\prm {xspaceskip}}]
+
+Normally the glue inserted when a space is encountered after a character with a
+space factor other than 1000 is taken from the font (fontdimen 7) unless this
+parameter is set in which case its value is added.
+
+\stopoldprimitive
+
+\startnewprimitive[title={\prm {xtoks}}]
+
+This is the global variant of \prm {etoks}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {xtoksapp}}]
+
+This is the global variant of \prm {etoksapp}.
+
+\stopnewprimitive
+
+\startnewprimitive[title={\prm {xtokspre}}]
+
+This is the global variant of \prm {etokspre}.
+
+\stopnewprimitive
+
+\startoldprimitive[title={\prm {year}}]
+
+This internal number starts out with the year that the job started.
+
+\stopoldprimitive
+
+\stopsubject
+
\startsubject[title=Obsolete]
The \LUAMETATEX\ engine has more than its \LUATEX\ ancestor but it also has less.
@@ -3122,6 +12518,27 @@ sort of used the same trick so there isn't much to gain and it was less generic
\page
+
+\definehead
+ [Syntax]
+ [subsection]
+% [style=\tta\bf,
+% numberwidth=2fs,
+% after=\blank\startpacked,
+% aftersection=\stoppacked]
+
+\startsubject[title=Syntax]
+
+\startpagecolumns[page=no]
+ \startluacode
+ moduledata.engine.allspecifications()
+ \stopluacode
+\stoppagecolumns
+
+\stopsubject
+
+\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]
@@ -3286,7 +12703,7 @@ 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,
+of time I spent 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,
@@ -3294,6 +12711,17 @@ 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.
+Basically there are wo areas where the engine can evolve: the programming part
+and the rendering. In this manual we focus on the programming and writing the
+manual sort of influences how details get filled in. Rendering in more complex
+because there heuristics and usage plays a more dominant role. Good examples are
+the math, par and page builder. They were extended and features were added over
+time but improved rendering came later. Not all extensions are critical, some are
+there (and got added) in order to write more readable code but there is only so
+much one can do in that area. Occasionally a feature pops up that is a side
+effect of a challenge. No matter what gets added it might not affect complexity
+too much and definitely not impact performance significantly!
+
Hans Hagen \crlf Hasselt NL
\stopsubject
@@ -3308,17 +12736,21 @@ Hans Hagen \crlf Hasselt NL
local primitives = token.getprimitives()
local luametatex = { }
local indexed = { }
+ local everything = { }
for i=1,#primitives do
- local p = primitives[i]
- if p[4] == 4 then
- local name = p[3]
- if find(name,"U") or find (name,"math") then
+ local prim = primitives[i]
+ local name = prim[3]
+ if prim[4] == 4 then
+ if find(name,"U") or find(name,"math") then
-- ignore
luametatex[name] = nil
+ everything[name] = false
else
luametatex[name] = false
end
+ else
+ everything[name] = true
end
end
@@ -3331,13 +12763,14 @@ Hans Hagen \crlf Hasselt NL
luametatex[name] = true
end
indexed[name] = true
+ everything[name] = nil
end
end
end
collect(structures.registers.collected and structures.registers.collected.index)
- context("To be checked primitives:")
+ context.startsubject { title = "To be checked primitives (new)" }
context.blank()
context.startcolumns { n = 2 }
@@ -3349,9 +12782,51 @@ Hans Hagen \crlf Hasselt NL
end
end
context.stopcolumns()
+
+ context.page()
+
+ context.stopsubject()
+
+ everything[""] = nil
+ everything[" "] = nil
+
+ context.startsubject { title = "To be checked primitives (math)" }
+
+ context.blank()
+ context.startcolumns { n = 2 }
+ for k, v in table.sortedhash(everything) do
+ if not v then
+ context.dontleavehmode()
+ context.type(k)
+ context.crlf()
+ end
+ end
+ context.stopcolumns()
+
+ context("Many primitives starting with \\type{Umath} are math parameters that are discussed elsewhere, if at all.")
+
+ context.page()
+
+ context.stopsubject()
+
+ context.startsubject { title = "To be checked primitives (old)" }
+
context.blank()
+ context.startcolumns { n = 2 }
+ for k, v in table.sortedhash(everything) do
+ if v then
+ context.dontleavehmode()
+ context.type(k)
+ context.crlf()
+ end
+ end
+ context.stopcolumns()
+
+ context.page()
- context("Indexed primitives:")
+ context.stopsubject()
+
+ context.startsubject { title = "Indexed primitives" }
context.blank()
context.startcolumns { n = 2 }
@@ -3367,18 +12842,25 @@ Hans Hagen \crlf Hasselt NL
context.crlf()
end
context.stopcolumns()
- context.blank()
+ context.page()
+
+ context.stopsubject()
end
\stopluacode
-% \startmode[atpragma]
-% \startluacode
-% context.page()
-% document.CheckCompleteness()
-% \stopluacode
-% \stopmode
+\startmode[atpragma]
+ \startluacode
+ context.page()
+ document.CheckCompleteness()
+ \stopluacode
+
+% Run \type {s-system-syntax.mkxl} for a complete overview of the \LUAMETATEX\
+% primitives.
+\stopmode
\stopbodymatter
\stoptext
+
+% disk and math options: orphaned
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-graphics.tex b/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-graphics.tex
index 2246c1c885d..9c6fb232dd4 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-graphics.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/workflows/workflows-graphics.tex
@@ -198,6 +198,42 @@ images it might make sense to have a final run with a higher compress level. The
\stopsection
+\startsection[title=Remote]
+
+You can include images from a remote location using a \URL\ specification.
+
+\starttyping
+\externalfigure[https://www.pragma-ade.com/logo-ade.png] % via curl
+\externalfigure[http://www.pragma-ade.com/logo-ade.png] % via socket
+\stoptyping
+
+Normally the socket library will be used for \type {http} and Curl for \type
+{https}. Images are cached and there is some threshold that makes sure that we
+don't keep fetching. You can set the threshold to zero seconds to avoid that:
+
+\starttyping
+\enabledirectives[schemes.threshold=0]
+\stoptyping
+
+In \LMTX\ there are some more options:
+
+\starttyping
+\enabledirectives[schemes.inmemory]
+\enabledirectives[schemes.uselibrary]
+\stoptyping
+
+The first option avoid storing an image in a file and therefore consumes a bit
+more memory and the second one tries to use the Curl library instead of calling
+the program. If you want ot see what is going on you can use:
+
+\starttyping
+\enabletrackers[resolvers.schemes]
+\enabletrackers[graphics.locating]
+\enabletrackers[resolvers.virtual]
+\stoptyping
+
+\stopsection
+
\stopchapter
\stopcomponent
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
index 006088c2cb0..2690089fd1a 100644
--- 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
@@ -6,9 +6,9 @@
\startchapter[title={Parallel processing}]
-% \startsection[title={Introduction}]
+\startsection[title={Introduction}]
-% \stopsection
+\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
@@ -115,6 +115,123 @@ This permits a management script to check if a run is done. Before starting a ru
(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.
+\stopsection
+
+\startsection[title={Solution}]
+
+Mid 2023 the test suite had some 1900 files and whenever the engine or \CONTEXT\
+is adapted that collection of files is processed. Although one can test for
+regression the main reason for doing this is to check if any of these documents
+fails, which can happen due to some typo in an upgrade. We also want to see if
+there is a change in performance. However, for a single run it takes some 1350
+seconds (on my current development laptop), when two runs are needed we end up as
+2500 seconds. Of course a modern machine would likely bring that down to some 700
+seconds but there is only so much one can spend on hardware.
+
+Because \TEX\ is a single core process, the question is \quotation{Can we use
+more than one core?} and the answer is \quotation {Of course we can}. Running the
+test suite is managed by a (\LUA) script and one of its tasks is to traverse the
+tree of files and register success or failure so that at the end we get an
+overview. Parallelizing the process can be done in two ways: we divide the whole
+batch in several smaller batches where each batch is processed at the same time.
+Alternatively we can have one process that runs files in different threads (sort
+of).
+
+That second option is what we prefer and the runtime results of that one are as
+follows. We run on a four core mobile Xeon 1505 (with hyperthreading enabled):
+
+\starttabulate[|r|r|]
+\NC 6 \NC 800 \NC \NR
+\BC 8 \BC 700 \NC \NR
+\NC 12 \NC 650 \NC \NR
+\NC 16 \NC 600 \NC \NR
+\stoptabulate
+
+As a comparison, running multiple batches in parallel gives (in seconds):
+
+\starttabulate[|r|r|]
+\NC 4 \NC 550 \NC \NR
+\NC 6 \NC 540 \NC \NR
+\stoptabulate
+
+In the end I settled for the 8 runs in parallel, just because the machine ran
+less hot (and thereby less noisy) and one can still do plenty other things during
+that run. When one pipes the output to the terminal the graphic processor is also
+kept busy (some 50 percent for the built|-|in graphics).
+
+So how does that benefit users? A variant of this feature is now available in the
+\CONTEXT\ runner. Of course you could always do this:
+
+\starttyping
+context test1.tex test2.tex test3.tex test4.tex
+\stoptyping
+
+Here the files are processed in sequence. But you can now get a better
+performance:
+
+\starttyping
+context --parallel test1.tex test2.tex test3.tex test4.tex
+\stoptyping
+
+In case every test file needs different command line arguments you can do this
+instead:
+
+\starttyping
+context --parallellist test.cmd
+\stoptyping
+
+Where (on \MSWINDOWS) that file can look like:
+
+\starttyping
+context test1 --result=test-1
+context test2 --result=test-2
+context test3 --result=test-3
+context test4 --result=test-4
+\stoptyping
+
+Here the runner will just take the lines that start with \type {context} which
+means that you can still run that command file directly.
+
+By default the output is suppressed unless you pass \type {--terminal} as in:
+
+\starttyping
+context --parallel --terminal test1.tex test2.tex test3.tex test4.tex
+\stoptyping
+
+The only drawback in this parallel approach is that when one run stalls its
+output (for instance because some huge graphic is rendered) the others will wait
+a bit, just because we cycle through the runs. It also depends how console
+buffering is set up. In practice this will not have much impact.
+
+If you use the same input file with different output, you can use this setup:
+
+\starttyping
+context test-1 --mode=m-1 --forceinput=test
+context test-2 --mode=m-2 --forceinput=test
+context test-3 --mode=m-3 --forceinput=test
+context test-5 --mode=m-5 --forceinput=test
+context test-5 --mode=m-5 --forceinput=test
+context test-6 --mode=m-6 --forceinput=test
+\stoptyping
+
+Here the so called jobname will be the given filename \type {test-*} while thee
+input will come from \type {test.tex}. Using the same input files with a result
+specification doesn't work here because the multi|-|pass data file(s) and
+intermediate result will clash. Running on dedicated subpath could work out but
+has its own complications (creation, cleanup, moving results) and would therefore
+be more fragile.
+
+An example of running files in a tree, like those in the test suite is:
+
+\starttyping
+context --parallel --pattern=**/whatever*.tex
+\stoptyping
+
+The files will be processed the directory where the file is found. When there is
+an error the filename will be reported at the end of the run.
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-titlepage.tex b/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-titlepage.tex
index db36c93491c..362e5b6e75c 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-titlepage.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv-titlepage.tex
@@ -19,6 +19,8 @@
\useMPlibrary[punk]
+ \usetypescript[punk]
+
\definefont[PunkSmall][Serif*punkrandom @ 18pt]
\definefont[PunkLarge][Serif*punkrandom @ 90pt]
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv.tex b/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv.tex
index bf3df9c2d35..7ecfb220ef0 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/xml/xml-mkiv.tex
@@ -1,5 +1,7 @@
% language=us runpath=texruns:manuals/xml
+% engine=luatex
+
% author : Hans Hagen
% copyright : ConTeXt Development Team
% license : Creative Commons Attribution ShareAlike 4.0 International