From 0e813ddcd6168945510ca50913c00fc8b633b733 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Mon, 30 Nov 2020 11:17:53 +0100
Subject: 2020-11-30 10:23:00

---
 .../documents/general/manuals/lowlevel-macros.pdf  | Bin 87408 -> 87655 bytes
 .../documents/general/manuals/luametatex.pdf       | Bin 1232228 -> 1295270 bytes
 .../general/manuals/lowlevel/lowlevel-macros.tex   |  24 +-
 .../manuals/luametatex/luametatex-differences.tex  |  16 +-
 .../manuals/luametatex/luametatex-enhancements.tex | 259 ++++++++++++++++++++-
 .../manuals/luametatex/luametatex-introduction.tex |  45 ++--
 .../general/manuals/luametatex/luametatex.tex      |  28 ++-
 tex/context/base/mkii/cont-new.mkii                |   2 +-
 tex/context/base/mkii/context.mkii                 |   2 +-
 tex/context/base/mkiv/char-tex.lua                 |   2 +-
 tex/context/base/mkiv/cont-new.mkiv                |   2 +-
 tex/context/base/mkiv/context.mkiv                 |   2 +-
 tex/context/base/mkiv/math-ini.lua                 |  59 ++++-
 tex/context/base/mkiv/node-fnt.lua                 |   4 +-
 tex/context/base/mkiv/status-files.pdf             | Bin 26175 -> 26204 bytes
 tex/context/base/mkiv/status-lua.pdf               | Bin 256055 -> 256055 bytes
 tex/context/base/mkxl/anch-pgr.mkxl                |  28 +--
 tex/context/base/mkxl/anch-pos.mkxl                |   5 +
 tex/context/base/mkxl/anch-tab.mkxl                |   8 +-
 tex/context/base/mkxl/buff-par.mklx                |   6 +
 tex/context/base/mkxl/colo-ini.mkxl                |   4 +-
 tex/context/base/mkxl/cont-new.mkxl                |   2 +-
 tex/context/base/mkxl/context.mkxl                 |   2 +-
 tex/context/base/mkxl/core-sys.mkxl                |   4 +-
 tex/context/base/mkxl/enco-ini.mkxl                |   4 +-
 tex/context/base/mkxl/font-lib.mklx                |   6 +-
 tex/context/base/mkxl/grph-inc.mkxl                |   4 +-
 tex/context/base/mkxl/grph-trf.mkxl                |   8 +-
 tex/context/base/mkxl/math-inc.mkxl                |  12 +-
 tex/context/base/mkxl/math-ini.mkxl                |   8 +-
 tex/context/base/mkxl/node-fin.lmt                 | 146 +++++++++---
 tex/context/base/mkxl/pack-com.mkxl                |   2 +-
 tex/context/base/mkxl/pack-rul.mkxl                |  44 +---
 tex/context/base/mkxl/page-ffl.mkxl                |   4 +-
 tex/context/base/mkxl/page-flt.mkxl                |   5 +
 tex/context/base/mkxl/page-ini.mkxl                |   6 +-
 tex/context/base/mkxl/page-lay.mkxl                |   6 +-
 tex/context/base/mkxl/page-one.mkxl                |   2 +-
 tex/context/base/mkxl/publ-inc.mkxl                |  12 +-
 tex/context/base/mkxl/spac-ali.mkxl                |   2 +-
 tex/context/base/mkxl/strc-con.mklx                |   2 +-
 tex/context/base/mkxl/strc-flt.mklx                |  45 ++--
 tex/context/base/mkxl/strc-itm.mklx                |   4 +-
 tex/context/base/mkxl/strc-lst.mklx                |   6 +-
 tex/context/base/mkxl/strc-mat.mkxl                |   7 +-
 tex/context/base/mkxl/strc-not.mklx                |   4 +-
 tex/context/base/mkxl/strc-num.mkxl                |   1 -
 tex/context/base/mkxl/strc-ref.mklx                |  51 ++--
 tex/context/base/mkxl/strc-reg.mkxl                |   2 +-
 tex/context/base/mkxl/strc-ren.mkxl                |   4 +-
 tex/context/base/mkxl/strc-syn.mkxl                |  48 ++--
 tex/context/base/mkxl/strc-tag.mkxl                |   4 +-
 tex/context/base/mkxl/syst-aux.mkxl                |  12 +-
 tex/context/base/mkxl/tabl-ltb.mkxl                |  16 +-
 tex/context/base/mkxl/tabl-ntb.mkxl                |   4 +-
 tex/context/base/mkxl/tabl-tbl.mkxl                |  29 +--
 tex/context/base/mkxl/tabl-tsp.mkxl                |   4 +-
 tex/context/base/mkxl/tabl-xtb.mklx                |   4 +-
 tex/context/base/mkxl/trac-vis.lmt                 |  93 +++++---
 tex/context/base/mkxl/type-ini.mklx                |   4 +-
 tex/context/base/mkxl/typo-del.mkxl                |   4 +-
 tex/context/base/mkxl/typo-mar.mkxl                |   4 +-
 tex/generic/context/luatex/luatex-fonts-merged.lua |   2 +-
 63 files changed, 792 insertions(+), 337 deletions(-)

diff --git a/doc/context/documents/general/manuals/lowlevel-macros.pdf b/doc/context/documents/general/manuals/lowlevel-macros.pdf
index 8503e3045..63689f1c8 100644
Binary files a/doc/context/documents/general/manuals/lowlevel-macros.pdf and b/doc/context/documents/general/manuals/lowlevel-macros.pdf differ
diff --git a/doc/context/documents/general/manuals/luametatex.pdf b/doc/context/documents/general/manuals/luametatex.pdf
index a06bc7c1b..fcc9fa52f 100644
Binary files a/doc/context/documents/general/manuals/luametatex.pdf and b/doc/context/documents/general/manuals/luametatex.pdf differ
diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-macros.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-macros.tex
index 7ddfde2c5..ef527732b 100644
--- a/doc/context/sources/general/manuals/lowlevel/lowlevel-macros.tex
+++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-macros.tex
@@ -521,9 +521,27 @@ quit.
 I have to admit that I don't really need it but it made some macros that I was
 redefining behave better, so there is some self|-|interest here. Anyway, I
 considered some other features, like picking up a detokenized argument but I
-don't expect that to be of much use. In the meantime we ran out of reasonable characters,
-but some day \type {#?} and \type {#!} might show up, or maybe I find a use for \type {#<}
-and \type {#>}.
+don't expect that to be of much use. In the meantime we ran out of reasonable
+characters, but some day \type {#?} and \type {#!} might show up, or maybe I find
+a use for \type {#<} and \type {#>}. A summary of all this is given here:
+
+\starttabulate[|T|i2l|]
+\FL
+\NC +   \NC keep the braces \NC \NR
+\NC -   \NC discard and don't count the argument \NC \NR
+\NC /   \NC remove leading an trailing spaces and pars \NC \NR
+\NC =   \NC braces are mandate \NC \NR
+\NC _   \NC braces are mandate and kept \NC \NR
+\NC ^   \NC keep leading spaces \NC \NR
+\ML
+\NC 1-9 \NC an argument \NC \NR
+\NC 0   \NC discard but count the argument \NC \NR
+\ML
+\NC *   \NC ignore spaces \NC \NR
+\NC :   \NC pick up scanning here  \NC \NR
+\NC ;   \NC quit scanning \NC \NR
+\LL
+\stoptabulate
 
 \stopsection
 
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex b/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
index ba3b903b0..5b8f7558a 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
@@ -1,4 +1,4 @@
-% language=uk
+    % language=uk
 
 \environment luametatex-style
 
@@ -102,7 +102,8 @@ been removed. There are some new variants that will be discussed later. The \typ
 {\outer} and \type {\long} prefixes are gone as they don't make much sense
 nowadays and them becoming dummies opened the way to something new, again to be
 discussed elsewhere. I don't think that (\CONTEXT) users will notice it. The
-\type {\suppress..} features are now default.
+\type {\suppress..} features are now default and can't be changed so related
+primitives are gone.
 
 The \type {\shipout} primitive does no ship out but just erases the content of
 the box, if that hasn't happened already in another way.
@@ -208,10 +209,17 @@ might be noticed that it is not possible to backtrack or inject something. Of
 course it is no big deal to implement all that in \LUA\ if needed. It removes a
 system dependency and makes for a bit cleaner code.
 
-There are new primitives too as well as some extensions to existing primitive
+There are new primitives as well as some extensions to existing primitive
 functionality. These are described in following chapters but there might be
 hidden treasures in the binary. If you locate them, don't automatically assume
-them to stay, some might be part of experiments!
+them to stay, some might be part of experiments! There are for instance a few
+csname related definers, we have integer and dimension constants, the macro
+argument parser can be brought in tolerant mode, the repertoire of conditionals
+has been extended, some internals can be controlled (think of normalization of
+lines, hyphenation etc.), and macros can be protected against user overload. Not
+all is discussed in detail in this manual but there are introductions in the
+\CONTEXT\ distribution that explain them. But the \TEX\ kernel is of course
+omnipresent.
 
 \startluacode
 
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
index ee30683e8..f4dbfb15d 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
@@ -1110,6 +1110,13 @@ lead to less clutter in tracing.
 
 \stopsubsection
 
+\startsubsection[title={\lpr {ifrelax}}]
+
+This primitive complements \type {\ifdefined}, \type {\ifempty} and \type
+{\ifcsname} so that we have all reasonable tests directly available.
+
+\stopsubsection
+
 \startsubsection[title={\lpr {ifboolean}}]
 
 This primitive tests for non|-|zero, so the next variants are similar
@@ -1151,6 +1158,33 @@ one might evolve).
 
 \stopsubsection
 
+\startsubsection[title={\lpr {ifarguments}, \lpr {ifparameters} and \lpr {ifparameter}}]
+
+These are part of the extended macro argument parsing features. The \type
+{\ifarguments} condition is like an \type {\ifcase} where the number is the
+picked up number of arguments. The number reflects the {\em last} count, so
+successive macro expansions will adapt the value. The \type {\ifparameters}
+counts till the first empty parameter and the \type {\ifparameter} (singular)
+takes a parameter reference (like \type {#2}) and again is an \type {\ifcase}
+where zero means a bad reference, one a non|-|empty argument and two an empty
+one. A typical usage is:
+
+\starttyping
+\def\foo#1#2%
+  {\ifparameter#1\or one\fi
+   \ifparameter#2\or two\fi}
+\stoptyping
+
+No expansion of arguments takes place here but you can use a test like this:
+
+\starttyping
+\def\foo#1#2%
+  {\iftok{#1}{}\else one\fi
+   \iftok{#2}{}\else two\fi}
+\stoptyping
+
+\stopsubsection
+
 \startsubsection[title={\lpr {ifcondition}}]
 
 \topicindex {conditions}
@@ -1321,14 +1355,6 @@ dimensions are calculated.
 
 \stopsubsection
 
-\topicindex {splitting}
-
-The \prm {vsplit} primitive has to be followed by a specification of the required
-height. As alternative for the \type {to} keyword you can use \type {upto} to get
-a split of the given size but result has the natural dimensions then.
-
-\stopsubsection
-
 \startsubsection[title={\prm {vsplit}}]
 
 \topicindex {splitting}
@@ -1931,6 +1957,223 @@ makes sense (for integers).
 
 \stopsection
 
+\startsection[title=Macro arguments]
+
+Again this is experimental and (used and) discussed in document that come with the
+\CONTEXT\ distribution. When defining a macro you can do this:
+
+\starttyping
+\def\foo(#1)#2{...}
+\stoptyping
+
+Here the first argument between parentheses is mandate. But the magic
+prefix \lpr {tolerant} makes that limitation go away:
+
+\starttyping
+\tolerant\def\foo(#1)#2{...}
+\stoptyping
+
+A variant is this:
+
+\starttyping
+\tolerant\def\foo(#1)#*(#2){...}
+\stoptyping
+
+Here we have two optional arguments, possibly be separated by spaces. There are
+more parsing options:
+
+\starttabulate[|T|i2l|]
+\FL
+\NC +   \NC keep the braces \NC \NR
+\NC -   \NC discard and don't count the argument \NC \NR
+\NC /   \NC remove leading an trailing spaces and pars \NC \NR
+\NC =   \NC braces are mandate \NC \NR
+\NC _   \NC braces are mandate and kept \NC \NR
+\NC ^   \NC keep leading spaces \NC \NR
+\ML
+\NC 1-9 \NC an argument \NC \NR
+\NC 0   \NC discard but count the argument \NC \NR
+\ML
+\NC *   \NC ignore spaces \NC \NR
+\NC :   \NC pick up scanning here  \NC \NR
+\NC ;   \NC quit scanning \NC \NR
+\LL
+\stoptabulate
+
+For the moment we leave it to your fantasy what these options do. Most probably
+only make sense when you write a bit more complex macros. Just try to imagine
+what this does:
+
+\starttyping
+\permanent\tolerant\global\protected\def\foo(#1)#*#;[#2]#:#3{...}
+\stoptyping
+
+Of course complex combinations can be confusing because after all \TEX\ is
+parsing for (multi|-|token) delimiters and will happily gobble the whole file if
+you are not careful. You can quit scanning if you want:
+
+\starttyping
+\mymacro 123\ignorearguments
+\stoptyping
+
+which of course only makes sense when used in a nested call where an already
+picked up arguments is processed further. A not (yet) discussed feature of the
+parser is that it will happily skip tokens that have the (probably seldom used)
+ignored characters property.
+
+When you use tracing or see error messages arguments defined using for instance
+\type {#=} will have their usual number in the macro body, so you need to keep
+track of the numbers.
+
+All this is rather easy on the engine and although it might have a little impact
+on performance this has been compensated by some more efficiency in the macro
+parser and engine in general and of course you can gain back some by using these
+features.
+
+\stopsection
+
+\startsection[title=Overload protection]
+
+There is an experimental overload protection mechanism that we will test for a
+while before declaring it stable. The reason for that is that we need to adapt
+the \CONTEXT\ code base in order to test its usefulness. Protection is achieved
+via prefixes. Depending on the value of the \lpr {overloadmode} variable
+warnings or errors will be triggered. Examples of usage can be found in some
+documents that come with \CONTEXT, so here we just stick to the basics.
+
+\starttyping
+\mutable  \def\foo{...}
+\immutable\def\foo{...}
+\permanent\def\foo{...}
+\frozen   \def\foo{...}
+\aliased  \def\foo{...}
+\stoptyping
+
+A \lpr {mutable} macro can always be changed contrary to an \lpr {immutable} one.
+For instance a macro that acts as a variable is normally \lpr {mutable}, while a
+constant can best be immutable. It makes sense to define a public core macro as
+\lpr {permanent}. Primives start out a \lpr {permanent} ones but with a primitive
+property instead.
+
+\startbuffer
+          \let\relaxone  \relax 1: \meaningfull\relaxone
+\aliased  \let\relaxtwo  \relax 2: \meaningfull\relaxtwo
+\permanent\let\relaxthree\relax 3: \meaningfull\relaxthree
+\stopbuffer
+
+\typebuffer
+
+The \lpr {meaningfull} primitive is like \prm {meaning} but report the
+properties too. The \lpr {meaningless} companion reports the body of a macro.
+Anyway, this typesets:
+
+\startlines \tttf \getbuffer \stoplines
+
+So, the \lpr {aliased} prefix copies the properties. Keep in mind that a macro
+package can redefine primitives, but \prm {relax} is an unlikely candidate.
+
+There is an extra prefix \lpr {noaligned} that flags a macro as being valid
+for \prm {noalign} compatible usage (which means that the body must contain that
+one. The idea is that we then can do this:
+
+\starttyping
+\permanent\protected\noaligned\def\foo{\noalign{...}} % \foo is unexpandable
+\stoptyping
+
+that is: we can have protected macros that don't trigger an error in the parser
+where there is a look ahead for \prm {noalign} which is why normally protection
+doesn't work well. So: we have macro flagged as permanent (overload protection),
+being protected (that is, not expandable by default) and a valid equivalent of
+the noalign primitive. Of course we can also apply the \prm {global} and \lpr
+{tolerant} prefixes here. The complete repertoire of extra prefixes is:
+
+\starttabulate
+\HL
+\NC \type {frozen}     \NC a macro that has to be redefined in a managed way \NC \NR
+\NC \type {permanent}  \NC a macro that had better not be redefined \NC \NR
+\NC \type {primitive}  \NC a primitive that normally will not be adapted \NC \NR
+\NC \type {immutable}  \NC a macro or quantity that cannot be changed, it is a constant \NC \NR
+\NC \type {mutable}    \NC a macro that can be changed no matter how well protected it is \NC \NR
+\HL
+\NC \type {instance}   \NC a macro marked as (for instance) be generated by an interface \NC \NR
+\HL
+\NC \type {noaligned}  \NC the macro becomes acceptable as \type {\noalign} alias \NC \NR
+\HL
+\NC \type {overloaded} \NC when permitted the flags will be adapted \NC \NR
+\NC \type {enforced}   \NC all is permitted (but only in zero mode or ini mode) \NC \NR
+\NC \type {aliased}    \NC the macro gets the same flags as the original \NC \NR
+\HL
+\stoptabulate
+
+The not yet discussed \lpr {instance} is just a flag with no special meaning
+which can be used as classifier. The \lpr {frozen} also protects against overload
+which brings amount of blockers to four.
+
+To what extent the engine will complain when a property is changed in a way that
+violates the flags depends on the parameter \lpr {overloadmode}. When this
+parameter is set to zero no checking takes place. More interesting are values
+larger than zero. If that is the case, when a control sequence is flagged as
+mutable, it is always permitted to change. When it is set to immutable one can
+never change it. The other flags determine the kind of checking done. Currently
+the following overload values are used:
+
+\starttabulate[|l|l|c|c|c|c|c|]
+    \NC   \NC         \BC immutable \BC permanent \BC primitive \BC frozen \BC instance \NC \NR
+    \NC 1 \NC warning \NC \star     \NC \star     \NC \star     \NC        \NC          \NC \NR
+    \NC 2 \NC error   \NC \star     \NC \star     \NC \star     \NC        \NC          \NC \NR
+    \NC 3 \NC warning \NC \star     \NC \star     \NC \star     \NC \star  \NC          \NC \NR
+    \NC 4 \NC error   \NC \star     \NC \star     \NC \star     \NC \star  \NC          \NC \NR
+    \NC 5 \NC warning \NC \star     \NC \star     \NC \star     \NC \star  \NC \star    \NC \NR
+    \NC 6 \NC error   \NC \star     \NC \star     \NC \star     \NC \star  \NC \star    \NC \NR
+\stoptabulate
+
+The even values (except zero) will abort the run. A value of 255 will freeze this
+parameter. At level five and above the \lpr {instance} flag is also checked but
+no drastic action takes place. We use this to signal to the user that a specific
+instance is redefined (of course the definition macros can check for that too).
+
+The \lpr {overloaded} prefix can be used to overload a frozen macro. The \lpr
+{enforced} is more powerful and forces an overload but that prefix is only
+effective in ini mode or when it's embedded in the body of a macro or token list
+at ini time unless of course at runtime the mode is zero.
+
+So far for a short explanation. More details can be found in the \CONTEXT\
+documentation where we can discuss it in a more relevant perspective. It must be
+noted that this feature only makes sense a controlled situation, that is: user
+modules or macros of unpredictable origin will probably suffer from warnings and
+errors when de mode is set to non zero. In \CONTEXT\ we're okay unless of course
+users redefine instances but there a warning or error is kind of welcome.
+
+\stopsection
+
+\startsection[title=Constants]
+
+It is rather common to store constant values in a register or character
+definition.
+
+\starttyping
+\newcount\MyConstantA \MyConstantA 123
+\newdimen\MyConstantB \MyConstantB 123pt
+\chardef \MyConstantC \MyConstantC 123
+\stoptyping
+
+But in \LUAMETATEX\ we also can do this:
+
+\starttyping
+\integerdef\MyConstantC 456
+\dimendef  \MyConstantD 456pt
+\stoptyping
+
+These two are stored as efficient as a register but don't occupy a register slot.
+They can be set as above, need \prm {the} for serializations and are seen as
+valid number or dimension when needed.
+
+Experiments with constant strings made the engine source more complex than I
+wanted so that features was rejected. Of course we can use the prefixes mentioned
+in a previous section.
+
+\stopsection
+
 \startsection[title=Nodes]
 
 The \ETEX\ primitive \type {\lastnodetype} is not honest in reporting the
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex b/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex
index 1ad055a83..40c69aeef 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex-introduction.tex
@@ -138,30 +138,35 @@ real problem as there's not much demand for that anyway.
 versions which means that \LMTX\ is tested well. We can therefore safely claim
 that end of 2019 the code has become quite stable. There are no complaints about
 performance (on my 2013 laptop this manual compiles at 24.5 pps with \LMTX\
-versus 20.7 pps for the \LUATEX\ manual with \MKIV). Probably no one notices it,
-but memory consumption stepwise got reduced too. And \unknown\ the binary is
-still below 3~MegaBytes on all platforms.
+versus 20.7 pps for the \LUATEX\ manual with \MKIV). After updating some of the
+\CONTEXT\ code to use recently added features by the end of 2020 I could do more
+than 25.5 pps but don't expect spectacular bumps in performance (I need a new
+machine for that to happen). Probably no one notices it, but memory consumption
+stepwise got reduced too. And \unknown\ the binary is still below 3~MegaBytes on
+all platforms.
 
 \stopchapter
 
 \stopcomponent
 
-% I'm not that strict with incrementing numbers, but let's occasionally bump
-% the number. Once we're stable it might happen more systematically. For sure
-% I don't want to end up with these redicoulous 0.99999999 kind of numbers.
-%
+% I'm not that strict with incrementing numbers, but let's occasionally bump the
+% number. Once we're stable it might happen more systematically. For sure I don't
+% want to end up with these 0.99999999 kind of numbers.
+
 % We started with 2.00.0 and kept that number till November 2019, after Alan
-% Braslau and I did the initial beta release at April 1, 2019. After more than
-% a year working on the code base after the \CONTEXT\ 2019 meeting a state was
-% reached where nothing fundamental got added for a while. When \LUATEX\ needs
-% a patch, I check the \LUAMETATEX\ code base as the same patch might be needed
-% there. On the other hand, we don't need a strict compatibility, so some
-% patched in \LUATEX\ are not applied here.
+% Braslau and I did the initial beta release at April 1, 2019. After more than a
+% year working on the code base after the \CONTEXT\ 2019 meeting a state was
+% reached where nothing fundamental got added for a while. When \LUATEX\ needs a
+% patch, I check the \LUAMETATEX\ code base as the same patch might be needed
+% there. On the other hand, we don't need a strict compatibility, so some patched
+% in \LUATEX\ are not applied here.
+%
+% In November 2019 I started wondering if we should bump the number, just for the
+% sake of showing that there's still some progress. So I decided to bump to 2.01.0
+% then. Just as a reminder for myself: it was the day when I watched Jacob Collier
+% perform \LUA\ (feat. MARO) live on YouTube (of course that is not about the
+% language at all, but still a nice coincidence). Just for the fun of it the number
+qbumped a few more times, just to catch up, so end 2019 we're at 2.03.5.
 %
-% In November 2019 I started wondering if we should bump the number, just for
-% the sake of showing that there's still some progress. So I decided to bump to
-% 2.01.0 then. Just as a reminder for myself: it was the day when I watched
-% Jacob Collier perform Lua (feat. MARO) live on YouTube (of course that is not
-% about the language at all, but still a nice coincidence). Just for the fun of
-% it the number bumped a few more times, just to catch up, so end 2019 we're at
-% 2.03.5.
+% Thanks to the patient \CONTEXT\ users we were able to apply the new macro scanner
+% and protection mechanisms that were introduced mid 2020.
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex.tex b/doc/context/sources/general/manuals/luametatex/luametatex.tex
index 99cd6cfa5..e0e7f1575 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex.tex
@@ -1,13 +1,21 @@
-% ------------------------   ------------------------
-% 2019-12-17  32bit  64bit   2020-01-10  32bit  64bit
-% ------------------------   ------------------------
-% freebsd     2270k  2662k   freebsd     2186k  2558k
-% openbsd6.6  2569k  2824k   openbsd6.6  2472k  2722k
-% linux-armhf 2134k          linux-armhf 2063k
-% linux       2927k  2728k   linux       2804k  2613k
-% osx                2821k   osx                2732k
-% mswin       2562k  2555k   mswin       2481k  2471k
-% ------------------------   ------------------------
+% ------------------------   ------------------------   ------------------------
+% 2019-12-17  32bit  64bit   2020-01-10  32bit  64bit   2020-11-30  32bit  64bit
+% ------------------------   ------------------------   ------------------------
+% freebsd     2270k  2662k   freebsd     2186k  2558k   freebsd     2108k  2436k
+% openbsd6.6  2569k  2824k   openbsd6.6  2472k  2722k   openbsd6.8  2411k  2782k
+% linux-armhf 2134k          linux-armhf 2063k          linux-armhf 2138k  2860k
+% linux       2927k  2728k   linux       2804k  2613k   linux   (?) 3314k  2762k
+%                                                       linux-musl  2532k  2686k
+% osx                2821k   osx                2732k   osx                2711k
+% ms mingw    2562k  2555k   ms mingw    2481k  2471k   ms mingw    2754k  2760k
+%                                                       ms intel           2448k
+%                                                       ms arm             3894k
+%                                                       ms clang           2159k
+% ------------------------   ------------------------   ------------------------
+%
+% performance of mingw and native are getting close (small win for mingw) but
+% clang bins are still slower .. quite inconsistent differences between 32 and
+% 64 bit (not all compilers are the same version)
 
 % \loggingall
 % \tracingonline    \zerocount
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 054c99fe5..f3f004ad8 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2020.11.28 13:15}
+\newcontextversion{2020.11.30 10:20}
 
 %D This file is loaded at runtime, thereby providing an
 %D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index ef09b35d7..e4bc700cb 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
 %D your styles an modules.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2020.11.28 13:15}
+\edef\contextversion{2020.11.30 10:20}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/mkiv/char-tex.lua b/tex/context/base/mkiv/char-tex.lua
index 4580ae40a..7f544b147 100644
--- a/tex/context/base/mkiv/char-tex.lua
+++ b/tex/context/base/mkiv/char-tex.lua
@@ -681,7 +681,7 @@ if not csletters then
                         if isletter then
                             texsetmacro(contextname,utfchar(u),"immutable")
                         else
-                            texsetchar(contextname,u)
+                            texsetchar(contextname,u,"immutable")
                         end
                     else
                         texsetmacro(contextname,utfchar(u),"immutable")
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 972672192..fe5504ffe 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
 
 % \normalend % uncomment this to get the real base runtime
 
-\newcontextversion{2020.11.28 13:15}
+\newcontextversion{2020.11.30 10:20}
 
 %D This file is loaded at runtime, thereby providing an excellent place for hacks,
 %D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 540d6ea74..46eab5afe 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2020.11.28 13:15}
+\edef\contextversion{2020.11.30 10:20}
 
 %D Kind of special:
 
diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua
index b5c4581b7..5475f6f73 100644
--- a/tex/context/base/mkiv/math-ini.lua
+++ b/tex/context/base/mkiv/math-ini.lua
@@ -97,9 +97,17 @@ local classes = allocate {
     root        = 16, -- a private one
 }
 
-local open_class   = 4
-local middle_class = 4
-local close_class  = 5
+local open_class      =  4
+local middle_class    =  4
+local close_class     =  5
+local accent_class    =  8
+local radical_class   =  9
+local topaccent_class = 11
+local botaccent_class = 12
+local under_class     = 13
+local over_class      = 14
+local delimiter_class = 15
+local root_class      = 16
 
 local accents = allocate {
     accent    = true, -- some can be both
@@ -246,26 +254,55 @@ local f_char      = formatters[ [[\defUmathchar      \%s{%X}{%X}{%X}]] ]
 
 local texmathchardef = tex.mathchardef
 
+-- local setmathsymbol = function(name,class,family,slot) -- hex is nicer for tracing
+--     if class == classes.accent then
+--         ctx_sprint(f_topaccent(name,0,family,slot))
+--     elseif class == classes.topaccent then
+--         ctx_sprint(f_topaccent(name,0,family,slot))
+--     elseif class == classes.botaccent then
+--         ctx_sprint(f_botaccent(name,0,family,slot))
+--     elseif class == classes.over then
+--         ctx_sprint(f_over(name,0,family,slot))
+--     elseif class == classes.under then
+--         ctx_sprint(f_under(name,0,family,slot))
+--     elseif class == open_class or class == close_class or class == middle_class then
+--         setdelcode("global",slot,{family,slot,0,0})
+--         ctx_sprint(f_fence(name,class,family,slot))
+--     elseif class == classes.delimiter then
+--         setdelcode("global",slot,{family,slot,0,0})
+--         ctx_sprint(f_delimiter(name,0,family,slot))
+--     elseif class == classes.radical then
+--         ctx_sprint(f_radical(name,family,slot))
+--     elseif class == classes.root then
+--         ctx_sprint(f_root(name,family,slot))
+--     elseif texmathchardef then
+--         texmathchardef(name,class,family,slot,"permanent")
+--     else
+--         -- beware, open/close and other specials should not end up here
+--         ctx_sprint(f_char(name,class,family,slot))
+--     end
+-- end
+
 local setmathsymbol = function(name,class,family,slot) -- hex is nicer for tracing
-    if class == classes.accent then
+    if class == accent_class then
         ctx_sprint(f_topaccent(name,0,family,slot))
-    elseif class == classes.topaccent then
+    elseif class == topaccent_class then
         ctx_sprint(f_topaccent(name,0,family,slot))
-    elseif class == classes.botaccent then
+    elseif class == botaccent_class then
         ctx_sprint(f_botaccent(name,0,family,slot))
-    elseif class == classes.over then
+    elseif class == over_class then
         ctx_sprint(f_over(name,0,family,slot))
-    elseif class == classes.under then
+    elseif class == under_class then
         ctx_sprint(f_under(name,0,family,slot))
     elseif class == open_class or class == close_class or class == middle_class then
         setdelcode("global",slot,{family,slot,0,0})
         ctx_sprint(f_fence(name,class,family,slot))
-    elseif class == classes.delimiter then
+    elseif class == delimiter_class then
         setdelcode("global",slot,{family,slot,0,0})
         ctx_sprint(f_delimiter(name,0,family,slot))
-    elseif class == classes.radical then
+    elseif class == radical_class then
         ctx_sprint(f_radical(name,family,slot))
-    elseif class == classes.root then
+    elseif class == root_class then
         ctx_sprint(f_root(name,family,slot))
     elseif texmathchardef then
         texmathchardef(name,class,family,slot,"permanent")
diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua
index dd40befc8..f3bb6228f 100644
--- a/tex/context/base/mkiv/node-fnt.lua
+++ b/tex/context/base/mkiv/node-fnt.lua
@@ -138,8 +138,8 @@ fonts.hashes.processes   = fontprocesses
 -- inside a run which means that we need to keep track of this which in turn complicates matters
 -- in a way i don't like
 
--- we need to deal with the basemode fonts here and can only run over ranges as we
--- otherwise get luatex craches due to all kind of asserts in the disc/lig builder
+-- we need to deal with the basemode fonts here and can only run over ranges as we otherwise get
+-- luatex craches due to all kind of asserts in the disc/lig builder
 
 -- there is no gain in merging used (dynamic 0) and dynamics apart from a bit less code
 
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 5f0d5c4fa..dc575dca5 100644
Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 968ce190c..216c5f4c9 100644
Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ
diff --git a/tex/context/base/mkxl/anch-pgr.mkxl b/tex/context/base/mkxl/anch-pgr.mkxl
index d701fc14a..6b0fef441 100644
--- a/tex/context/base/mkxl/anch-pgr.mkxl
+++ b/tex/context/base/mkxl/anch-pgr.mkxl
@@ -97,22 +97,18 @@
 \def\anch_positions_cleanup_action % not in trialtypesetting
   {\ifcsname\??positioncleanup\currentpositionaction\endcsname
      \the\everycleanpositionaction
-     \xdefcsname\??positioncleanup\currentpositionaction\endcsname
-       {\csname\??positioncleanup\currentpositionaction\endcsname}%
+     \xdefcsname\??positioncleanup\currentpositionaction\endcsname{\csname\??positioncleanup\currentpositionaction\endcsname}%
    \fi}
 
 \permanent\protected\def\handlepositionaction#1\with#2\on#3% ugly, will change
   {\begingroup
-   \edef\currentpositionanchor
-     {\ifempty\currentpositionoverlay#3\else\currentpositionoverlay::\MPanchoridentifier\fi}%
-   \normalexpanded{\anch_positions_set_action{\currentpositionanchor}{\noexpand\getvalue{\??positioncleanup\currentpositionanchor}}}%
+   \edef\currentpositionanchor{\ifempty\currentpositionoverlay#3\else\currentpositionoverlay::\MPanchoridentifier\fi}%
+   \normalexpanded{\anch_positions_set_action{\currentpositionanchor}{\noexpand\csname\??positioncleanup\currentpositionanchor\endcsname}}%
    \let#1\relax
    \ifcsname\??positioncleanup\currentpositionanchor\endcsname
-     \xdefcsname\??positioncleanup\currentpositionanchor\endcsname
-       {\csname\??positioncleanup\currentpositionanchor\endcsname#1#2}%
+     \xdefcsname\??positioncleanup\currentpositionanchor\endcsname{\csname\??positioncleanup\currentpositionanchor\endcsname#1#2}%
    \else
-     \xdefcsname\??positioncleanup\currentpositionanchor\endcsname
-       {#1#2}%
+     \xdefcsname\??positioncleanup\currentpositionanchor\endcsname{#1#2}%
    \fi
    \endgroup}
 
@@ -345,18 +341,6 @@
      \expandafter\gobbletwoarguments
    \fi{#1}{#2}}
 
-% \unexpanded\def\MPpositiongraphic
-%   {\dodoublegroupempty\anch_positions_meta_graphic_direct}
-
-% \def\anch_positions_meta_graphic_direct#1% tag setups
-%   {\ifcsname\??positionmethod#1\endcsname % method
-%      \expandafter\anch_positions_meta_graphic_direct_indeed_method
-%    \else\ifcsname\??positiongraphic#1\endcsname
-%      \doubleexpandafter\anch_positions_meta_graphic_direct_indeed_normal
-%    \else
-%      \doubleexpandafter\anch_positions_meta_graphic_direct_indeed_unknown
-%    \fi\fi{#1}}
-
 \def\anch_positions_meta_graphic_direct_method{\anch_positions_meta_graphic_direct\??positionmethod }
 \def\anch_positions_meta_graphic_direct_normal{\anch_positions_meta_graphic_direct\??positiongraphic}
 
@@ -367,7 +351,7 @@
    \anch_positions_meta_graphic_prepare
    \obeyMPboxorigin % do we also set the size ? when needed this must be done in mp ... might change
    \enforced\tolerant\protected\def\MPpositiongraphic##=##*##={\anch_positions_meta_graphic_nested{#3}{##1}{##2}}% takes two extra arguments
-%    \def\anch_positions_meta_graphic_direct{\anch_positions_meta_graphic_nested{#3}}% takes two extra arguments
+ % \def\anch_positions_meta_graphic_direct{\anch_positions_meta_graphic_nested{#3}}% takes two extra arguments
    \setbox\b_anch_positions_graphic\hbox % \hpack
      {\ignorespaces\begincsname#1#2\endcsname\removelastspace}%
    \smashbox\b_anch_positions_graphic
diff --git a/tex/context/base/mkxl/anch-pos.mkxl b/tex/context/base/mkxl/anch-pos.mkxl
index 6a2fbd5e1..3075a9ab6 100644
--- a/tex/context/base/mkxl/anch-pos.mkxl
+++ b/tex/context/base/mkxl/anch-pos.mkxl
@@ -46,6 +46,11 @@
 \newbox\b_anch_position
 \newif \ifpositioning   % sort of public
 
+\mutable\let\currentposition      \empty
+\mutable\let\currentpositionaction\empty
+\mutable\let\currentpositionanchor\empty
+\mutable\let\currentpositionregion\empty
+
 %D Sometimes we want to trick the position handler a bit:
 
 % \replacepospxywhd #1#2#3#4#5#6#7 % defined at lua end
diff --git a/tex/context/base/mkxl/anch-tab.mkxl b/tex/context/base/mkxl/anch-tab.mkxl
index 8f4bb0b5b..48e4ae4cb 100644
--- a/tex/context/base/mkxl/anch-tab.mkxl
+++ b/tex/context/base/mkxl/anch-tab.mkxl
@@ -84,7 +84,7 @@
 
 \permanent\def\tbPOSprefix{\??positiontables\number\noftabpositions:}
 
-\protected\def\tablepos
+\permanent\protected\def\tablepos
   {\normalexpanded{\global\posXCtoks\emptytoks\the\posXCtoks}}
 
 \permanent\protected\def\tbXC {\anch_table_checked\anch_tables_indeed_XC }
@@ -170,7 +170,7 @@
 
 \aliased\let\tabulatepos\tablepos
 
-\def\tabulatenormalpos
+\permanent\protected\def\tabulatenormalpos
   {\iftrialtypesetting
      % nothing
    \orelse\ifconditional\tablehaspositions
@@ -179,7 +179,7 @@
      % nothing
    \fi}
 
-\def\tabulateequalpos
+\permanent\protected\def\tabulateequalpos
   {\iftrialtypesetting
      \tabulateEQ
    \orelse\ifconditional\tablehaspositions
@@ -188,7 +188,7 @@
      \tabulateEQ
    \fi}
 
-\def\tabulateEQpos
+\permanent\protected\def\tabulateEQpos
   {\setbox\scratchbox\hbox{\tabulateEQ}%
    \hbox to \wd\scratchbox{\hss\kern\zeropoint\tabulatepos\hss}% hpack
    \kern-\wd\scratchbox
diff --git a/tex/context/base/mkxl/buff-par.mklx b/tex/context/base/mkxl/buff-par.mklx
index 663ea7254..4b762ff04 100644
--- a/tex/context/base/mkxl/buff-par.mklx
+++ b/tex/context/base/mkxl/buff-par.mklx
@@ -131,6 +131,12 @@
    \relax
    \endgroup}
 
+\mutable\let\currentparallelinstance\empty
+\mutable\let\currentparallelnumber  \empty
+\mutable\let\currentparallelline    \empty
+\mutable\let\currentparallellabel   \empty
+\mutable\let\currentparallelcontent \empty
+
 \def\doflushparallel#instance#status#line#label#content% called at lua end
   {\begingroup
    \def\currentparallelinstance{#instance}%
diff --git a/tex/context/base/mkxl/colo-ini.mkxl b/tex/context/base/mkxl/colo-ini.mkxl
index e6ec0d103..cad33514b 100644
--- a/tex/context/base/mkxl/colo-ini.mkxl
+++ b/tex/context/base/mkxl/colo-ini.mkxl
@@ -759,7 +759,7 @@
 
 % so far
 
-\def\colo_helpers_activate#1% two-step is not that much faster but less tracing
+\permanent\protected\def\colo_helpers_activate#1% two-step is not that much faster but less tracing
   {\edef\currentcolorname{#1}%
    \ifempty\currentcolorprefix
     %\expandafter
@@ -796,7 +796,7 @@
      \lastnamedcs
    \fi}
 
-\let\dousecolorparameter\colo_helpers_activate
+\aliased\let\dousecolorparameter\colo_helpers_activate
 
 \permanent\protected\def\dousecolorhashparameter#1#2%
   {\ifcsname#1#2\endcsname
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index f89d21f4a..f4ce10be5 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
 
 % \normalend % uncomment this to get the real base runtime
 
-\newcontextversion{2020.11.28 13:15}
+\newcontextversion{2020.11.30 10:20}
 
 %D This file is loaded at runtime, thereby providing an excellent place for hacks,
 %D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index 3d5b46d49..613e650de 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2020.11.28 13:15}
+\immutable\edef\contextversion{2020.11.30 10:20}
 
 %overloadmode 1 % check frozen / warning
 %overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/core-sys.mkxl b/tex/context/base/mkxl/core-sys.mkxl
index bcf216c0a..302cdaa99 100644
--- a/tex/context/base/mkxl/core-sys.mkxl
+++ b/tex/context/base/mkxl/core-sys.mkxl
@@ -192,7 +192,7 @@
     \frozen\setuevalue        {\currentstartstop}{\syst_startstop_indeed{\currentstartstop}}%
 \to \everydefinestartstop
 
-\ifdefined\dotagconstruct \else \let\dotagconstruct\relax \fi
+\ifdefined\dotagconstruct \else \aliased\let\dotagconstruct\relax \fi
 
 \protected\def\syst_startstop_start#1%
   {\namedstartstopparameter{#1}\c!before\relax
@@ -244,7 +244,7 @@
     \fi
 \to \everydefinehighlight
 
-\ifdefined\dotaghighlight \else \let\dotaghighlight\relax \fi
+\ifdefined\dotaghighlight \else \aliased\let\dotaghighlight\relax \fi
 
 \permanent\protected\def\typo_highlights_indeed#1% inline style/color switch
   {\dontleavehmode\groupedcommand % otherwise wrong par number in tags
diff --git a/tex/context/base/mkxl/enco-ini.mkxl b/tex/context/base/mkxl/enco-ini.mkxl
index 1f8a121d5..6dd800bf3 100644
--- a/tex/context/base/mkxl/enco-ini.mkxl
+++ b/tex/context/base/mkxl/enco-ini.mkxl
@@ -382,7 +382,9 @@
 
 \permanent\protected\def\normalunderscore{\ifmmode\mathunderscore\else\textunderscore\fi}
 
-\let\_\normalunderscore
+\pushoverloadmode
+    \let\_\normalunderscore
+\popoverloadmode
 
 %D To be sorted out:
 
diff --git a/tex/context/base/mkxl/font-lib.mklx b/tex/context/base/mkxl/font-lib.mklx
index 509e8ed86..780611148 100644
--- a/tex/context/base/mkxl/font-lib.mklx
+++ b/tex/context/base/mkxl/font-lib.mklx
@@ -159,8 +159,10 @@
 \permanent\protected\def\typethreelast#1{\char#1\relax}
 \permanent\protected\def\typethreecode#1{\pdfliteral direct {#1}}
 
-\newtoks\typethreetoks
-\let    \typethreemacro\empty
+% This might change ...
+
+\newtoks    \typethreetoks         % used at the lua end
+\mutable\let\typethreemacro\empty  % used at the lua end
 
 \typethreetoks {%
     \setbox\zerocount\hpack{\typethreemacro}%
diff --git a/tex/context/base/mkxl/grph-inc.mkxl b/tex/context/base/mkxl/grph-inc.mkxl
index 21be4abf6..024db290e 100644
--- a/tex/context/base/mkxl/grph-inc.mkxl
+++ b/tex/context/base/mkxl/grph-inc.mkxl
@@ -40,7 +40,7 @@
 %D moved from modules to the core. The overall functionality is rather stable and has
 %D not changed much over the years.
 
-\ifdefined\dotagfigure \else \let\dotagfigure\relax \fi
+\ifdefined\dotagfigure \else \aliased\let\dotagfigure\relax \fi
 
 \installcorenamespace{externalfigure}
 \installcorenamespace{externalfigureinstance}
@@ -251,7 +251,7 @@
 \newtoks\t_grph_include_local_settings
 
 \appendtoks
-   \let\textunderscore\letterunderscore % {\string _} % space needed as _ is now letter in unprotected mode (probably no longer needed)
+   \enforced\let\textunderscore\letterunderscore % {\string _} % space needed as _ is now letter in unprotected mode (probably no longer needed)
    %
    \dontcomplain
    \restorecatcodes
diff --git a/tex/context/base/mkxl/grph-trf.mkxl b/tex/context/base/mkxl/grph-trf.mkxl
index 3f5b3a4b0..87e4da7f4 100644
--- a/tex/context/base/mkxl/grph-trf.mkxl
+++ b/tex/context/base/mkxl/grph-trf.mkxl
@@ -67,10 +67,10 @@
 
 % public:
 
-\let\finalscaleboxxscale \!!plusone
-\let\finalscaleboxyscale \!!plusone
-\let\finalscaleboxwidth  \!!zeropoint
-\let\finalscaleboxheight \!!zeropoint
+\mutable\let\finalscaleboxxscale \!!plusone
+\mutable\let\finalscaleboxyscale \!!plusone
+\mutable\let\finalscaleboxwidth  \!!zeropoint
+\mutable\let\finalscaleboxheight \!!zeropoint
 
 % we can let sx/sy win (first check)
 
diff --git a/tex/context/base/mkxl/math-inc.mkxl b/tex/context/base/mkxl/math-inc.mkxl
index c23684fd3..4db75e37e 100644
--- a/tex/context/base/mkxl/math-inc.mkxl
+++ b/tex/context/base/mkxl/math-inc.mkxl
@@ -40,23 +40,23 @@
    \relax}
 
 \permanent\protected\def\xmlattachmml
-  {\iftrialtypesetting \else \ifexporting \iflocation
+  {\iftrialtypesetting\orelse\ifexporting\iflocation
      \dostarttagged\t!ignore\empty
        \lxml_add_mml_blob{mmlattachment}\attachment
      \dostoptagged
-   \fi \fi \fi}
+   \fi\fi}
 
 \permanent\protected\def\xmlcommentmml
-  {\iftrialtypesetting \else \ifexporting \iflocation
+  {\iftrialtypesetting\orelse\ifexporting\iflocation
      \dostarttagged\t!ignore\empty
        \lxml_add_mml_blob{mmlcomment}\comment
      \dostoptagged
-   \fi \fi \fi}
+   \fi\fi}
 
 %D This kind of feature creep is not yet configurable, nor documented.
 
 \permanent\protected\def\xmladdmmlsource
-  {\iftrialtypesetting \else \ifexporting \iflocation
+  {\iftrialtypesetting\orelse\ifexporting\iflocation
      \dostarttagged\t!ignore\empty
      \inleftmargin{%
        \lxml_add_mml_blob{mmlattachment}\attachment
@@ -64,6 +64,6 @@
        \lxml_add_mml_blob{mmlcomment}\comment
      }%
      \dostoptagged
-   \fi \fi \fi}
+   \fi\fi}
 
 \protect \endinput
diff --git a/tex/context/base/mkxl/math-ini.mkxl b/tex/context/base/mkxl/math-ini.mkxl
index 91946bcdb..d806af427 100644
--- a/tex/context/base/mkxl/math-ini.mkxl
+++ b/tex/context/base/mkxl/math-ini.mkxl
@@ -452,10 +452,10 @@
 
 % no longer needed now we have enforce so the next few lines will go
 
-\pushoverloadmode
-    \enforced\let\dotlessi\dotlessi
-    \enforced\let\dotlessj\dotlessj
-\popoverloadmode
+% \pushoverloadmode
+%     \enforced\let\dotlessi\dotlessi
+%     \enforced\let\dotlessj\dotlessj
+% \popoverloadmode
 
 \permanent\protected\def\mathaltcalligraphic{\setmathfontalternate{calligraphic}\cal}          % set via goody file
 \permanent\protected\def\mathaltitalic      {\setmathfontalternate{italic}}                    % set via goody file
diff --git a/tex/context/base/mkxl/node-fin.lmt b/tex/context/base/mkxl/node-fin.lmt
index 6d29ed57f..dab90863a 100644
--- a/tex/context/base/mkxl/node-fin.lmt
+++ b/tex/context/base/mkxl/node-fin.lmt
@@ -634,6 +634,102 @@ end
 
 -- experimental
 
+-- local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise
+--
+--  -- nsbegin()
+--     local stacked  = false
+--
+--     local current  = head
+--     local previous = head
+--     local attrib   = default or unsetvalue
+--     local check    = false
+--     local leader   = false
+--
+--     while current do
+--         local id = getid(current)
+--         if id == glyph_code then
+--             check = true
+--         elseif id == glue_code then
+--             leader = getleader(current)
+--             if leader then
+--                 check = true
+--             end
+--         elseif id == hlist_code or id == vlist_code then
+--             local content = getlist(current)
+--             if content then
+--                 local list
+--                 if nslistwise then
+--                     local a = getattr(current,attribute)
+--                     if a and attrib ~= a and nslistwise[a] then -- viewerlayer
+--                         head = insert_node_before(head,current,copy_node(nsdata[a]))
+--                         list = stacker(attribute,content,a)
+--                         if list ~= content then
+--                             setlist(current,list)
+--                         end
+--                         head, current = insert_node_after(head,current,copy_node(nsnone))
+--                     else
+--                         list = stacker(attribute,content,attrib)
+--                         if list ~= content then
+--                             setlist(current,list)
+--                         end
+--                     end
+--                 else
+--                     list = stacker(attribute,content,default)
+--                     if list ~= content then
+--                         setlist(current,list)
+--                     end
+--                 end
+--             end
+--         elseif id == rule_code then
+--             check = has_dimensions(current)
+--         end
+--
+--         if check then
+--             local a = getattr(current,attribute) or unsetvalue
+--             if a ~= attrib then
+--                 if not stacked then
+--                     stacked = true
+--                     nsbegin()
+--                 end
+--                 local n = nsstep(a)
+--                 if n then
+--                     head = insert_node_before(head,current,n) -- a
+--                 end
+--                 attrib = a
+--                 if leader then
+--                     -- tricky as a leader has to be a list so we cannot inject before
+--                  -- local list = stacker(attribute,leader,attrib)
+--                  -- leader = false
+--
+--                     local content = getlist(leader)
+--                     if content then
+--                         local list = stacker(attribute,leader,attrib)
+--                         if leader ~= list then
+--                             setleader(current,list)
+--                         end
+--                     end
+--
+--                     leader = false
+--                 end
+--             end
+--             check = false
+--         end
+--
+--         previous = current
+--         current = getnext(current)
+--     end
+--
+--     if stacked then
+--         local n = nsend()
+--         while n do
+--             head = insert_node_after(head,previous,n)
+--             n = nsend()
+--         end
+--     end
+--
+--     return head
+-- end
+
 local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise
 
  -- nsbegin()
@@ -645,43 +741,42 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
     local check    = false
     local leader   = false
 
-    while current do
-        local id = getid(current)
+    for current, id, subtype, content in nextcontent, head do
         if id == glyph_code then
             check = true
         elseif id == glue_code then
-            leader = getleader(current)
-            if leader then
-                check = true
-            end
+            leader = content
+            check  = true
         elseif id == hlist_code or id == vlist_code then
-            local content = getlist(current)
-            if content then
-                local list
-                if nslistwise then
-                    local a = getattr(current,attribute)
-                    if a and attrib ~= a and nslistwise[a] then -- viewerlayer
-                        head = insert_node_before(head,current,copy_node(nsdata[a]))
-                        list = stacker(attribute,content,a)
-                        if list ~= content then
-                            setlist(current,list)
-                        end
-                        head, current = insert_node_after(head,current,copy_node(nsnone))
-                    else
-                        list = stacker(attribute,content,attrib)
-                        if list ~= content then
-                            setlist(current,list)
-                        end
+            local list
+            if nslistwise then
+                local a = getattr(current,attribute)
+                if a and attrib ~= a and nslistwise[a] then -- viewerlayer
+                    head = insert_node_before(head,current,copy_node(nsdata[a]))
+                    list = stacker(attribute,content,a)
+                    if list ~= content then
+                        setlist(current,list)
                     end
+                    head, current = insert_node_after(head,current,copy_node(nsnone))
                 else
-                    list = stacker(attribute,content,default)
+                    list = stacker(attribute,content,attrib)
                     if list ~= content then
                         setlist(current,list)
                     end
                 end
+            else
+                list = stacker(attribute,content,default)
+                if list ~= content then
+                    setlist(current,list)
+                end
             end
         elseif id == rule_code then
-            check = has_dimensions(current)
+            if subtype == boxrule_code or subtype == imagerule_code or subtype == emptyrule_code then
+                -- so no redundant color stuff (only here, layers for instance should obey)
+                check = false
+            else
+                check = has_dimensions(current)
+            end
         end
 
         if check then
@@ -716,7 +811,6 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
         end
 
         previous = current
-        current = getnext(current)
     end
 
     if stacked then
diff --git a/tex/context/base/mkxl/pack-com.mkxl b/tex/context/base/mkxl/pack-com.mkxl
index 21511f6b3..9b39bf900 100644
--- a/tex/context/base/mkxl/pack-com.mkxl
+++ b/tex/context/base/mkxl/pack-com.mkxl
@@ -67,7 +67,7 @@
 %D \stopcombination
 %D \stoptyping
 
-\ifdefined\dotagcombination \else \let\dotagcombination\relax \fi
+\ifdefined\dotagcombination \else \aliased\let\dotagcombination\relax \fi
 
 \newsystemmode{combination}
 
diff --git a/tex/context/base/mkxl/pack-rul.mkxl b/tex/context/base/mkxl/pack-rul.mkxl
index 8ca6c69d5..18a667dd6 100644
--- a/tex/context/base/mkxl/pack-rul.mkxl
+++ b/tex/context/base/mkxl/pack-rul.mkxl
@@ -53,9 +53,9 @@
 
 \installcommandhandler \??framed {framed} \??framed
 
-\let\pack_framed_framedparameter    \framedparameter
-\let\pack_framed_framedparameterhash\framedparameterhash
-\let\pack_framed_setupcurrentframed \setupcurrentframed
+\aliased\let\pack_framed_framedparameter    \framedparameter
+\aliased\let\pack_framed_framedparameterhash\framedparameterhash
+\aliased\let\pack_framed_setupcurrentframed \setupcurrentframed
 
 \def\pack_framed_initialize
   {\enforced\let\framedparameter    \pack_framed_framedparameter
@@ -1657,23 +1657,6 @@
 %   \framed[width=2cm,align=middle,location=middle] {location\\equals\\middle}
 %   B}
 
-% \installframedlocator \v!hanging % best with strut=no
-%   {}
-%   {\dp\b_framed_normal\ht\b_framed_normal
-%    \ht\b_framed_normal\zeropoint}
-%
-% \installframedlocator \v!depth
-%   {}
-%   {\ht\b_framed_normal\dimexpr\ht\b_framed_normal-\strutdp\relax
-%    \dp\b_framed_normal\strutdp
-%    \box\b_framed_normal}
-%
-% \installframedlocator \v!height
-%   {}
-%   {\dp\b_framed_normal\dimexpr\ht\b_framed_normal-\strutht\relax
-%    \ht\b_framed_normal\strutht
-%    \box\b_framed_normal}
-
 \installframedlocator \v!hanging % best with strut=no *1* / see mail to list by SB
   {}
   {\scratchdimen\ht\b_framed_normal
@@ -2623,9 +2606,9 @@
    \c!margin=\v!standard]
 
 \appendtoks
-    \frozen\instance\setuevalue{\e!start\currentframedtext}{\pack_framed_text_start {\currentframedtext}}%
-    \frozen\instance\setuevalue{\e!stop \currentframedtext}{\pack_framed_text_stop                      }%
-    \frozen\instance\setuevalue        {\currentframedtext}{\pack_framed_text_direct[\currentframedtext]}%
+    \frozen\instance\protected\edefcsname\e!start\currentframedtext\endcsname{\pack_framed_text_start [\currentframedtext]}%
+    \frozen\instance\protected\edefcsname\e!stop \currentframedtext\endcsname{\pack_framed_text_stop                      }%
+    \frozen\instance\protected\edefcsname        \currentframedtext\endcsname{\pack_framed_text_direct[\currentframedtext]}%
 \to \everydefineframedtext
 
 \setvalue{\??framedtextlocation\v!left  }{\letframedtextparameter\c!left \relax
@@ -2641,15 +2624,12 @@
                                           \letframedtextparameter\c!right\relax
                                           \settrue\c_framed_text_location_none}
 
-\protected\def\pack_framed_text_start#1%
+\tolerant\protected\def\pack_framed_text_start[#1]#*[#2]#*[#3]% or #1#*[#2]#*[#3]% and pass {#1}
   {\bgroup
-   \edef\currentframedtext{#1}%
-   \dodoubleempty\pack_framed_text_start_indeed}
-
-\def\pack_framed_text_start_indeed[#1][#2]%
-  {\doifelseassignment{#1}
-     {\pack_framed_text_start_continue\empty{#1}}
-     {\pack_framed_text_start_continue{#1}{#2}}}
+   \edef\currentframedtext{#1}
+   \doifelseassignment{#2}
+     {\pack_framed_text_start_continue\empty{#2}}
+     {\pack_framed_text_start_continue{#2}{#3}}}
 
 % todo: sort out first/lastline ht/dp
 
@@ -2779,7 +2759,7 @@
   {\bgroup
    \edef\currentframedtext{#1}%
    \usebodyfontparameter\framedtextparameter
-   \setupcurrentframedtext[#1]%
+   \setupcurrentframedtext[#2]%
    \edef\p_framed_text_strut{\framedtextparameter\c!strut}%
    \letframedtextparameter\c!strut\v!no
    \inheritedframedtextframed\bgroup
diff --git a/tex/context/base/mkxl/page-ffl.mkxl b/tex/context/base/mkxl/page-ffl.mkxl
index 4bf685265..de016fdf6 100644
--- a/tex/context/base/mkxl/page-ffl.mkxl
+++ b/tex/context/base/mkxl/page-ffl.mkxl
@@ -106,7 +106,7 @@
      \fi
    \fi}
 
-\def\strc_floats_facing_flush_indeed
+\permanent\protected\def\strc_floats_facing_flush_indeed
   {\global\advance\c_strc_floats_facing_flushed\plusone
    \floatingpenalty\zerocount
    \insert\namedinsertionnumber\s!topfloat\bgroup
@@ -128,7 +128,7 @@
      \resetboxesincache{\currentfacingfloat}%
    \fi}
 
-\let\flushfacingfloats\strc_floats_facing_flush
+\aliased\let\flushfacingfloats\strc_floats_facing_flush
 
 \protected\def\strc_floats_facing_setup
   {\edef\currentfacingfloat{\currentfacingfloat:\m_strc_floats_state}%
diff --git a/tex/context/base/mkxl/page-flt.mkxl b/tex/context/base/mkxl/page-flt.mkxl
index 55c6b177f..b6049833e 100644
--- a/tex/context/base/mkxl/page-flt.mkxl
+++ b/tex/context/base/mkxl/page-flt.mkxl
@@ -182,6 +182,11 @@
 %
 % \placefloatwithsetups[somefigure]{}{\externalfigure[dummy][width=5cm,height=2cm]}
 
+\mutable\let\floatsetupcaption\empty
+\mutable\let\floatsetupcontent\empty
+\mutable\let\floatsetupwidth  \empty
+\mutable\let\floatsetupheight \empty
+
 \permanent\tolerant\protected\def\placefloatwithsetups[#1]#*[#2]#*[#3]#:#4%
   {\def\floatsetupcaption{#4}%
    \def\floatsetupcontent{\copy\nextbox}%
diff --git a/tex/context/base/mkxl/page-ini.mkxl b/tex/context/base/mkxl/page-ini.mkxl
index 481e5abd5..e78f759a8 100644
--- a/tex/context/base/mkxl/page-ini.mkxl
+++ b/tex/context/base/mkxl/page-ini.mkxl
@@ -189,7 +189,7 @@
 \def\page_otr_add_special_content
   {\dowithnextboxcs\page_otr_add_special_content_indeed\hbox}
 
-\def\page_otr_add_special_content_indeed
+\permanent\protected\def\page_otr_add_special_content_indeed
   {\wd\nextbox\zeropoint
    \ht\nextbox\zeropoint
    \dp\nextbox\zeropoint
@@ -197,9 +197,9 @@
      {%\hskip-\maxdimen                    % not here, fails in acrobat (clips)
       \box\b_page_otr_special\box\nextbox}}% was \unhbox, is now box again
 
-\let\flushatshipout\page_otr_add_special_content
+\aliased\let\flushatshipout\page_otr_add_special_content % this might go away
 
-\maxdeadcycles=1000
+\maxdeadcycles\plusthousand
 
 \newtoks\afterpage     \newtoks\aftereverypage
 \newtoks\beforepage    \newtoks\beforeeverypage
diff --git a/tex/context/base/mkxl/page-lay.mkxl b/tex/context/base/mkxl/page-lay.mkxl
index 9c84844bf..6cd0d9579 100644
--- a/tex/context/base/mkxl/page-lay.mkxl
+++ b/tex/context/base/mkxl/page-lay.mkxl
@@ -1229,9 +1229,9 @@
 \def\swapmargins % name will change, frozen?
   {\doifelsemarginswap\relax\doswapmargins}
 
-\def\doswapmargins % name will change, frozen?
-  {\let\swapmargins  \relax % to prevent local swapping
-   \let\doswapmargins\relax % to prevent local swapping
+\permanent\protected\def\doswapmargins
+  {\enforced\let\swapmargins  \relax % to prevent local swapping
+   \enforced\let\doswapmargins\relax % to prevent local swapping
    \the\everyswapmargins}
 
 \permanent\def\rightorleftpageaction
diff --git a/tex/context/base/mkxl/page-one.mkxl b/tex/context/base/mkxl/page-one.mkxl
index 3e7d3e2a8..2169c6018 100644
--- a/tex/context/base/mkxl/page-one.mkxl
+++ b/tex/context/base/mkxl/page-one.mkxl
@@ -608,7 +608,7 @@
         \nonoindentation
       \fi}}
 
-\def\floatautofactor{.5}
+\mutable\def\floatautofactor{.5}
 
 \def\page_one_place_float_auto_top_bottom
   {\ifx\floatmethod\v!auto
diff --git a/tex/context/base/mkxl/publ-inc.mkxl b/tex/context/base/mkxl/publ-inc.mkxl
index 8e6cd2bdf..9beae595f 100644
--- a/tex/context/base/mkxl/publ-inc.mkxl
+++ b/tex/context/base/mkxl/publ-inc.mkxl
@@ -33,23 +33,23 @@
    \relax}
 
 \permanent\protected\def\btxattach
-  {\iftrialtypesetting \else \ifexporting \iflocation
+  {\iftrialtypesetting\orelse\ifexporting\iflocation
      \dostarttagged\t!ignore\empty
        \btx_add_blob{btxattachment}\attachment
      \dostoptagged
-   \fi \fi \fi}
+   \fi\fi}
 
 \permanent\protected\def\btxcomment
-  {\iftrialtypesetting \else \ifexporting \iflocation
+  {\iftrialtypesetting\orelse\ifexporting\iflocation
      \dostarttagged\t!ignore\empty
        \btx_add_blob{btxcomment}\comment
      \dostoptagged
-   \fi \fi \fi}
+   \fi\fi}
 
 %D This kind of feature creep is not yet configurable, nor documented.
 
 \permanent\protected\def\btxaddsource
-  {\iftrialtypesetting \else \ifexporting \iflocation
+  {\iftrialtypesetting\orelse\ifexporting\iflocation
      \dostarttagged\t!ignore\empty
      \llap{%
        \btx_add_blob{btxattachment}\attachment
@@ -58,6 +58,6 @@
        \hskip\leftmargindistance
      }%
      \dostoptagged
-   \fi \fi \fi}
+   \fi\fi}
 
 \protect \endinput
diff --git a/tex/context/base/mkxl/spac-ali.mkxl b/tex/context/base/mkxl/spac-ali.mkxl
index d72371659..d0530d138 100644
--- a/tex/context/base/mkxl/spac-ali.mkxl
+++ b/tex/context/base/mkxl/spac-ali.mkxl
@@ -583,7 +583,7 @@
      \expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname
    \fi}
 
-\let\dosetraggedcommand\spac_align_prepare % sort of public
+\aliased\let\dosetraggedcommand\spac_align_prepare % sort of public
 
 % The regular align setter:
 
diff --git a/tex/context/base/mkxl/strc-con.mklx b/tex/context/base/mkxl/strc-con.mklx
index 21213a330..ddaa9e570 100644
--- a/tex/context/base/mkxl/strc-con.mklx
+++ b/tex/context/base/mkxl/strc-con.mklx
@@ -206,7 +206,7 @@
 %D Also, passing the title as argument has some history so we need to keep that as
 %D well.
 
-% \ifdefined\dotagsetconstruction \else \let\dotagsetconstruction\relax \fi
+% \ifdefined\dotagsetconstruction \else \aliased\let\dotagsetconstruction\relax \fi
 
 % \startuseMPgraphic{MyFrame}
 %     picture p ; numeric o ; path a, b ; pair c ;
diff --git a/tex/context/base/mkxl/strc-flt.mklx b/tex/context/base/mkxl/strc-flt.mklx
index 31622a336..d2a1551d9 100644
--- a/tex/context/base/mkxl/strc-flt.mklx
+++ b/tex/context/base/mkxl/strc-flt.mklx
@@ -321,8 +321,12 @@
 
 %D Captions.
 
-\let\floatcaptionsuffix\empty % an optional suffix
-\let\floatcaptionnumber\empty % a logical counter
+\mutable\let\floatcaptionarrangement\empty
+\mutable\let\floatcaptionattribute  \empty
+\mutable\let\floatcaptiondirectives \empty
+\mutable\let\floatcaptionlocation   \empty
+\mutable\let\floatcaptionnumber     \empty
+\mutable\let\floatcaptionsuffix     \empty
 
 % For a while these were placeholders:
 %
@@ -601,11 +605,11 @@
 
 % place
 
-\let\floatlabel         \empty
-\let\floatcolumn        \empty
-\let\floatrow           \empty
-\let\floatlocation      \empty
-\let\floatlocationmethod\empty
+\mutable\let\floatlabel         \empty
+\mutable\let\floatcolumn        \empty
+\mutable\let\floatrow           \empty
+\mutable\let\floatlocation      \empty
+\mutable\let\floatlocationmethod\empty
 
 \def\strc_floats_analyze_location
   {% more will be moved here
@@ -624,7 +628,7 @@
     \setupfloat[\c!spacebefore=\v!none,\c!spaceafter=\v!none]%
 \to \c_floats_every_table_float
 
-\ifdefined\dotagregisterfloat \else \let\dotagregisterfloat\gobbletwoarguments \fi
+\ifdefined\dotagregisterfloat \else \aliased\let\dotagregisterfloat\gobbletwoarguments \fi
 
 \tolerant\def\strc_floats_place[#tag]#spacer[#location]#spacer[#reference]#:#caption%
   {\strc_floats_set_current_tag{#tag}%
@@ -774,7 +778,7 @@
 \ifdefined\page_margin_strc_floats_before    \else \let\page_margin_strc_floats_before   \relax \fi
 \ifdefined\page_margin_strc_floats_set_hsize \else \let\page_margin_strc_floats_set_hsize\relax \fi
 
-\def\flushfloatslist
+\immutable\def\flushfloatslist
   {\v!left,\v!right,\v!inner,\v!outer,%
    \v!backspace,\v!cutspace,%
    \v!inleft,\v!inright,\v!inmargin,%
@@ -1266,12 +1270,13 @@
 \permanent\protected\def\hangsidefloat[#number]%
   {\global\c_page_sides_n_of_lines#number\relax}
 
+\mutable\let\extrafloatlocation\empty
+
 \def\strc_floats_set_extra_action#rightpagelocation#leftpagelocation%
   {\rightorleftpageaction
      {\let\extrafloatlocation#rightpagelocation}%
      {\let\extrafloatlocation#leftpagelocation}}
 
-\let\extrafloatlocation\empty
 
 \installcorenamespace{extrafloataction}
 
@@ -2419,11 +2424,13 @@
 
 \installcorenamespace{floatmethods}
 
-\let\floatmethod      \empty % set by lua
-\let\floatlabel       \empty % set by lua
-\let\floatcolumn      \empty % set by lua
-\let\floatrow         \empty % set by lua
-\let\forcedfloatmethod\empty % set by lua and floatcombinations
+\mutable\let\floatmethod       \empty % set by lua
+\mutable\let\floatlabel        \empty % set by lua
+\mutable\let\floatcolumn       \empty % set by lua
+\mutable\let\floatrow          \empty % set by lua
+\mutable\let\floatspecification\empty
+
+\mutable\let\forcedfloatmethod \empty % set by lua and floatcombinations
 
 \permanent\protected\def\setfloatmethodvariables#1% \floatmethod \floatlabel \floatrow \floatcolumn
   {\clf_analysefloatmethod{#1}} % move definition to lua end
@@ -2433,14 +2440,6 @@
 
 \def\strc_floats_get_box
   {\ifvisible
-%      \let\floatlabel \empty
-%      \let\floatcolumn\empty
-%      \let\floatrow   \empty
-%      \setfloatmethodvariables\floatlocation
-     % todo: nog algemeen otr
-%      \ifdefined\OTRSETsetpreferedcolumnslot
-%        \OTRSETsetpreferedcolumnslot\floatcolumn\floatrow
-%      \fi
      \ifcsname\??floatmethods\currentoutputroutine:\floatmethod\endcsname \else
         \let\floatmethod\v!here
      \fi
diff --git a/tex/context/base/mkxl/strc-itm.mklx b/tex/context/base/mkxl/strc-itm.mklx
index e2f2244a5..33d5c324d 100644
--- a/tex/context/base/mkxl/strc-itm.mklx
+++ b/tex/context/base/mkxl/strc-itm.mklx
@@ -530,8 +530,8 @@
      \lastnamedcs
    \fi}
 
-\ifdefined\dotagsetitemgroup \else \let\dotagsetitemgroup\relax             \fi
-\ifdefined\dotagsetitem      \else \let\dotagsetitem     \gobbleoneargument \fi
+\ifdefined\dotagsetitemgroup \else \aliased\let\dotagsetitemgroup\relax             \fi
+\ifdefined\dotagsetitem      \else \aliased\let\dotagsetitem     \gobbleoneargument \fi
 
 \def\strc_itemgroups_tag_start_group
   {\dostarttaggedchained\t!itemgroup\currentparentitemgroup\??itemgroup
diff --git a/tex/context/base/mkxl/strc-lst.mklx b/tex/context/base/mkxl/strc-lst.mklx
index df2eb6e0f..0b8c2e2a3 100644
--- a/tex/context/base/mkxl/strc-lst.mklx
+++ b/tex/context/base/mkxl/strc-lst.mklx
@@ -495,7 +495,7 @@
 \permanent\def\usestructurelistprocessor#tag%
   {\csname\??structurelistprocessor#tag\endcsname}
 
-\let\dotaglistlocation\relax
+\aliased\let\dotaglistlocation\relax
 
 \def\strc_lists_entry_process_default
   {no list method}
@@ -1097,10 +1097,10 @@
                     \hangindent\dimexpr\wd\b_strc_lists_number+\scratchdistance\relax
                     \hangafter\ifx\p_hang\v!no\zerocount\else\plusone\fi
                     \scratchdimen\listalternativeparameter\c!distance\relax
-                    \ifzeropt\wd\b_strc_lists_page \else \ifdim\scratchdimen>\zeropoint\relax
+                    \ifzeropt\wd\b_strc_lists_page\orelse\ifdim\scratchdimen>\zeropoint\relax
                         \rightskip\scratchdimen\s!plus\listalternativeparameter\c!stretch\relax
                         \parfillskip-\rightskip
-                    \fi \fi
+                    \fi
                 \else
                     \scratchdistance\zeropoint
                 \fi
diff --git a/tex/context/base/mkxl/strc-mat.mkxl b/tex/context/base/mkxl/strc-mat.mkxl
index 991c3202e..f69422edc 100644
--- a/tex/context/base/mkxl/strc-mat.mkxl
+++ b/tex/context/base/mkxl/strc-mat.mkxl
@@ -935,7 +935,7 @@
 
 \newcount\c_strc_formulas_n
 
-\ifdefined\dotagregisterformula \else \let\dotagregisterformula\gobbleoneargument \fi
+\ifdefined\dotagregisterformula \else \aliased\let\dotagregisterformula\gobbleoneargument \fi
 
 \protected\def\strc_formulas_stop_formula
   {\strc_formulas_place_number % in case it hasn't happened yet
@@ -1194,8 +1194,9 @@
 % \startplaceformula[title=whatever] \startformula e=mc^2 \stopformula \stopplaceformula
 % \startplaceformula[suffix=x]       \startformula e=mc^2 \stopformula \stopplaceformula
 
-\let\currentplaceformulareference\empty
-\let\currentplaceformulasuffix   \empty
+\mutable\let\currentplaceformulatitle    \empty
+\mutable\let\currentplaceformulareference\empty
+\mutable\let\currentplaceformulasuffix   \empty
 
 \permanent\tolerant\protected\def\startplaceformula[#1]%
   {\begingroup
diff --git a/tex/context/base/mkxl/strc-not.mklx b/tex/context/base/mkxl/strc-not.mklx
index c07cd2085..cc5455bc6 100644
--- a/tex/context/base/mkxl/strc-not.mklx
+++ b/tex/context/base/mkxl/strc-not.mklx
@@ -21,8 +21,8 @@
 % todo: more p_strc_notations_* (outside trial loop)
 % todo: see if we can now use \insertpenalties (>0 == some left)
 
-\ifdefined\dotagsetnotesymbol \else \let\dotagsetnotesymbol\relax \fi
-\ifdefined\dotagsetnotation   \else \let\dotagsetnotation  \relax \fi
+\ifdefined\dotagsetnotesymbol \else \aliased\let\dotagsetnotesymbol\relax \fi
+\ifdefined\dotagsetnotation   \else \aliased\let\dotagsetnotation  \relax \fi
 
 \permanent\protected\def\unvboxed {\ifvmode\unvbox \else\box \fi} % will change or used more often
 \permanent\protected\def\unvcopied{\ifvmode\unvcopy\else\copy\fi} % will change or used more often
diff --git a/tex/context/base/mkxl/strc-num.mkxl b/tex/context/base/mkxl/strc-num.mkxl
index f5adcf09a..8cf6039b1 100644
--- a/tex/context/base/mkxl/strc-num.mkxl
+++ b/tex/context/base/mkxl/strc-num.mkxl
@@ -353,7 +353,6 @@
 \aliased\let \convertednumber       \convertedcounter       % [name]
 
 \aliased\let \doifdefinednumber     \doifdefinedcounter     % {number}{true}
-\aliased\let \doifundefinednumber   \doifnotdefinedcounter  % {number}{true}
 \aliased\let \doifelsedefinednumber \doifelsedefinedcounter % {number}{true}{false}
 \aliased\let \doifdefinednumberelse \doifelsedefinedcounter % {number}{true}{false}
 
diff --git a/tex/context/base/mkxl/strc-ref.mklx b/tex/context/base/mkxl/strc-ref.mklx
index 10100fa03..758f2855f 100644
--- a/tex/context/base/mkxl/strc-ref.mklx
+++ b/tex/context/base/mkxl/strc-ref.mklx
@@ -75,12 +75,12 @@
 \mutable\let\currentreferenceformattype    \empty
 \mutable\let\currentreferencekind          \empty
 \mutable\let\currentreferencelabels        \empty
-\mutable\let\currentreferencenumber        \empty
+%mutable\let\currentreferencenumber        \empty
 \mutable\let\currentreferenceorder         \empty
-\mutable\let\currentreferencepage          \empty
-\mutable\let\currentreferencerealpage      \empty
-\mutable\let\currentreferencetext          \empty
-\mutable\let\currentreferencetitle         \empty
+%mutable\let\currentreferencepage          \empty
+%mutable\let\currentreferencerealpage      \empty
+%mutable\let\currentreferencetext          \empty
+%mutable\let\currentreferencetitle         \empty
 \mutable\let\currentreferenceuserdata      \empty
 
 
@@ -572,12 +572,11 @@
 %D
 %D We also use the odd/even characteristic to determine the page state.
 
-\let\currentrealreference      \empty
-\let\currentpagereference      \empty
-\let\currenttextreference      \empty
-\let\currentreferenceorder     \empty
-\let\currentsubtextreference   \empty
-\let\currentsubsubtextreference\empty
+\mutable\let\currentrealreference      \empty
+\mutable\let\currentpagereference      \empty
+\mutable\let\currenttextreference      \empty
+\mutable\let\currentsubtextreference   \empty
+\mutable\let\currentsubsubtextreference\empty
 
 \newcount\referencehastexstate % set in backend
 
@@ -973,22 +972,24 @@
 %D active (and when asked for, typeset in a different color and typeface).
 
 \appendtoks
-    \ifdefined\in    \let\normalmathin   \in    \protected\def\in   {\mathortext\normalmathin   \strc_references_in   } \else \let\in   \strc_references_in    \fi
-    \ifdefined\at    \let\normalmathat   \at    \protected\def\at   {\mathortext\normalmathat   \strc_references_at   } \else \let\at   \strc_references_at    \fi
-    \ifdefined\about \let\normalmathabout\about \protected\def\about{\mathortext\normalmathabout\strc_references_about} \else \let\about\strc_references_about \fi
-    \ifdefined\from  \let\normalmathfrom \from  \protected\def\from {\mathortext\normalmathfrom \strc_references_from } \else \let\from \strc_references_from  \fi
-    \ifdefined\over  \let\normalmathover \over  \protected\def\over {\mathortext\normalmathover \strc_references_about} \else \let\over \strc_references_about \fi
+    % likely math
+    \ifdefined\in    \aliased\let\normalmathin   \in    \permanent\protected\def\in   {\mathortext\normalmathin   \strc_references_in   } \else \aliased\let\in   \strc_references_in    \fi
+    \ifdefined\over  \aliased\let\normalmathover \over  \permanent\protected\def\over {\mathortext\normalmathover \strc_references_about} \else \aliased\let\over \strc_references_about \fi
+    %
+    \ifdefined\at    \aliased\let\normalmathat   \at    \permanent\protected\def\at   {\mathortext\normalmathat   \strc_references_at   } \else \aliased\let\at   \strc_references_at    \fi
+    \ifdefined\about \aliased\let\normalmathabout\about \permanent\protected\def\about{\mathortext\normalmathabout\strc_references_about} \else \aliased\let\about\strc_references_about \fi
+    \ifdefined\from  \aliased\let\normalmathfrom \from  \permanent\protected\def\from {\mathortext\normalmathfrom \strc_references_from } \else \aliased\let\from \strc_references_from  \fi
 \to \everydump
 
 \permanent          \def\filterreference  #key{\clf_filterreference{#key}} % no checking, expandable
 \permanent\protected\def\getreferenceentry#key{\clf_filterreference{#key}} % no checking, not expandable
 
-\def\currentreferencenumber  {\clf_filterreference{number}}
-\def\currentreferencepage    {\clf_filterreference{page}}
-\def\currentreferencetitle   {\clf_filterreference{title}}
-\def\currentreferencetext    {\clf_filterreference{text}}
-\def\currentreferencedefault {\clf_filterreference{default}}
-\def\currentreferencerealpage{\clf_filterreference{realpage}}
+\permanent\def\currentreferencenumber  {\clf_filterreference{number}}
+\permanent\def\currentreferencepage    {\clf_filterreference{page}}
+\permanent\def\currentreferencetitle   {\clf_filterreference{title}}
+\permanent\def\currentreferencetext    {\clf_filterreference{text}}
+%permanent\def\currentreferencedefault {\clf_filterreference{default}}
+\permanent\def\currentreferencerealpage{\clf_filterreference{realpage}}
 
 %D The most straightforward way of retrieving references is using \type {\ref}.
 
@@ -1003,7 +1004,7 @@
 
 %D Special cases:
 
-\protected\def\strc_references_about[#label]%
+\permanent\protected\def\strc_references_about[#label]%
   {\dontleavehmode
    \begingroup
    \enforced\let\crlf\space
@@ -1284,12 +1285,12 @@
       \goto{\referencesequence}[#3]}%
    \strc_references_stop_goto}
 
-\protected\def\strc_references_in
+\permanent\protected\def\strc_references_in
   {\strc_references_start_goto
    \let\currentreferencecontent\currentreferencedefault
    \strc_references_pickup_goto}
 
-\protected\def\strc_references_at
+\permanent\protected\def\strc_references_at
   {\strc_references_start_goto
    \let\currentreferencecontent\currentreferencepage
    \strc_references_pickup_goto}
diff --git a/tex/context/base/mkxl/strc-reg.mkxl b/tex/context/base/mkxl/strc-reg.mkxl
index 38ecae4a7..af98ca481 100644
--- a/tex/context/base/mkxl/strc-reg.mkxl
+++ b/tex/context/base/mkxl/strc-reg.mkxl
@@ -371,7 +371,7 @@
    \dostoptagged
    \endgroup}
 
-\let\dotagregisterlocation\relax % experiment
+\aliased\let\dotagregisterlocation\relax % experiment
 
 \tolerant\protected\def\strc_registers_insert_entry[#1]#*[#2]%
   {\def\currentregister{#1}%
diff --git a/tex/context/base/mkxl/strc-ren.mkxl b/tex/context/base/mkxl/strc-ren.mkxl
index 2d553964b..d0baacb04 100644
--- a/tex/context/base/mkxl/strc-ren.mkxl
+++ b/tex/context/base/mkxl/strc-ren.mkxl
@@ -89,11 +89,11 @@
    \fi}
 
 \permanent\def\setinlineheadreferenceattributes
-  {\ifconditional\headisdisplay \else \iflocation
+  {\ifconditional\headisdisplay\orelse\iflocation
      \c_attr_destination\currentstructureattribute
      \c_attr_reference  \currentstructurereferenceattribute
    % \c_attr_internal   \locationcount
-   \fi \fi}
+   \fi}
 
 \permanent\protected\def\docheckheadreference
   {\edef\currentheadinteraction{\headparameter\c!interaction}%
diff --git a/tex/context/base/mkxl/strc-syn.mkxl b/tex/context/base/mkxl/strc-syn.mkxl
index 6f2f255d5..13147a99f 100644
--- a/tex/context/base/mkxl/strc-syn.mkxl
+++ b/tex/context/base/mkxl/strc-syn.mkxl
@@ -184,7 +184,7 @@
     \settrue\c_strc_constructions_define_commands
 \to \everydefinesimplelist
 
-\setuvalue{\??constructioninitializer\v!simplelist}%
+\protected\defcsname\??constructioninitializer\v!simplelist\endcsname
   {\let         \currentsimplelist               \currentconstruction
    \enforced\let\constructionparameter           \simplelistparameter
    \enforced\let\constructionnamespace           \??simplelist
@@ -193,10 +193,10 @@
    \enforced\let\useconstructionstyleandcolor    \usesimpleliststyleandcolor
    \enforced\let\setupcurrentconstruction        \setupcurrentsimplelist}
 
-\setuvalue{\??constructionfinalizer\v!simplelist}%
+\protected\defcsname\??constructionfinalizer\v!simplelist\endcsname
   {}
 
-\setuvalue{\??constructiontexthandler\v!simplelist}%
+\protected\defcsname\??constructiontexthandler\v!simplelist\endcsname
   {\begingroup
    \useconstructionstyleandcolor\c!headstyle\c!headcolor
    \the\everyconstruction
@@ -207,8 +207,8 @@
 
 % And we build on top of this.
 
-\ifdefined\dotagsynonym \else \let\dotagsynonym\relax \fi
-\ifdefined\dotagsorting \else \let\dotagsorting\relax \fi
+\ifdefined\dotagsynonym \else \aliased\let\dotagsynonym\relax \fi
+\ifdefined\dotagsorting \else \aliased\let\dotagsorting\relax \fi
 
 \definesimplelist
   [\v!synonym]
@@ -233,12 +233,21 @@
 
 \aliased\let\setupsynonyms\setupsimplelist
 
+% these  might become private
+
+\mutable\let\currentsynonymoption   \empty
+\mutable\let\currentsynonymcoding   \empty
+\mutable\let\currentsynonymexpansion\empty
+\mutable\let\currentsynonym         \empty
+\mutable\let\currentsynonymtag      \empty
+\mutable\let\currentsynonymtext     \empty
+
 \permanent\tolerant\protected\def\definesynonyms[#1]#*[#2]#*[#3]#*[#4]% name plural \meaning \use
   {\ifnum\lastarguments=\plusfour
      \protected\instance\def#4##1{\strc_synonyms_insert{#1}{##1}}% name tag
-     \frozen\instance\setuvalue{#1}{\definesynonym[\v!no][#1]}% \name
+     \frozen\instance\protected\defcsname#1\endcsname{\definesynonym[\v!no][#1]}% \name
    \else
-     \frozen\instance\setuvalue{#1}{\definesynonym[\v!yes][#1]}% \name
+     \frozen\instance\protected\defcsname#1\endcsname{\definesynonym[\v!yes][#1]}% \name
    \fi
    \ifparameter#3\or
      \frozen\instance\protected\def#3##1{\strc_synonyms_insert_meaning{#1}{##1}}% \meaning
@@ -260,9 +269,9 @@
      %
      % These will go away. Actually the overloads catched this empty case!
      %
-     \frozen\instance\setuvalue{\e!setup #2\e!endsetup}{\setupsynonyms[#1]}% obsolete definition
-     \frozen\instance\setuvalue{\e!place   \e!listof#2}{\placelistofsynonyms[#1]}% accepts extra argument
-     \frozen\instance\setuvalue{\e!complete\e!listof#2}{\completelistofsynonyms[#1]}%
+     \frozen\instance\protected\defcsname\e!setup #2\e!endsetup\endcsname{\setupsynonyms[#1]}% obsolete definition
+     \frozen\instance\protected\defcsname\e!place   \e!listof#2\endcsname{\placelistofsynonyms[#1]}% accepts extra argument
+     \frozen\instance\protected\defcsname\e!complete\e!listof#2\endcsname{\completelistofsynonyms[#1]}%
    \fi}
 
 \permanent\tolerant\protected\def\definesynonym[#1]#*[#2]#*[#3]%
@@ -467,15 +476,24 @@
 
 % if #3=\relax or \v!none, then no command but still protected
 
+% these  might become private
+
+\mutable\let\currentsortingoption   \empty
+\mutable\let\currentsortingcoding   \empty
+\mutable\let\currentsortingexpansion\empty
+\mutable\let\currentsorting         \empty
+\mutable\let\currentsortingtag      \empty
+\mutable\let\currentsortingtext     \empty
+
 \permanent\tolerant\protected\def\definesorting[#1]#*[#2]#*[#3]%
   {\ifnum\lastarguments=\plusthree
      \doifnot{#3}\v!none
        {\ifx#3\relax \else
           \protected\instance\def#3##1{\strc_sorting_insert{#1}{##1}}%
         \fi}%
-     \frozen\instance\setuvalue{#1}{\definesort[\v!no][#1]}%
+     \frozen\instance\protected\defcsname#1\endcsname{\definesort[\v!no][#1]}%
    \else
-     \frozen\instance\setuvalue{#1}{\definesort[\v!yes][#1]}%
+     \frozen\instance\protected\defcsname#1\endcsname{\definesort[\v!yes][#1]}%
    \fi
    \edef\currentsorting{#1}%
    \setfalse\c_strc_constructions_define_commands
@@ -494,9 +512,9 @@
      %
      \presetheadtext[#2=\Word{#2}]%
      %
-     \frozen\instance\setuvalue{\e!setup #2\e!endsetup}{\setupsorting[#1]}% obsolete definition
-     \frozen\instance\setuvalue{\e!place   \e!listof#2}{\placelistofsorts[#1]}%
-     \frozen\instance\setuvalue{\e!complete\e!listof#2}{\completelistofsorts[#1]}%
+     \frozen\instance\protected\defcsname\e!setup #2\e!endsetup\endcsname{\setupsorting[#1]}% obsolete definition
+     \frozen\instance\protected\defcsname\e!place   \e!listof#2\endcsname{\placelistofsorts[#1]}%
+     \frozen\instance\protected\defcsname\e!complete\e!listof#2\endcsname{\completelistofsorts[#1]}%
    \fi}
 
 \permanent\tolerant\protected\def\definesort[#1]#*[#2]#*[#3]%
diff --git a/tex/context/base/mkxl/strc-tag.mkxl b/tex/context/base/mkxl/strc-tag.mkxl
index 08d8fef6c..18cb65760 100644
--- a/tex/context/base/mkxl/strc-tag.mkxl
+++ b/tex/context/base/mkxl/strc-tag.mkxl
@@ -296,7 +296,7 @@
 
 \newconditional\c_strc_tags_enabled
 
-\permanent\let\dotaggedplaceholder\empty
+\aliased\let\dotaggedplaceholder\empty
 
 \immutable\chardef\strc_tags_placeholder_char\zerocount % "FFFC
 
@@ -396,7 +396,7 @@
   [\c!color=,
    \c!style=]
 
-\ifdefined\dotagparagraph \else \let\dotagparagraph\gobbleoneargument \fi
+\ifdefined\dotagparagraph \else \aliased\let\dotagparagraph\gobbleoneargument \fi
 
 \permanent\tolerant\protected\def\startparagraph[#1]#*[#2]%
   {\endgraf % we end before the group
diff --git a/tex/context/base/mkxl/syst-aux.mkxl b/tex/context/base/mkxl/syst-aux.mkxl
index 057aa5e98..7a60e63bb 100644
--- a/tex/context/base/mkxl/syst-aux.mkxl
+++ b/tex/context/base/mkxl/syst-aux.mkxl
@@ -5083,8 +5083,8 @@
    \ifdone\expandafter#1\else\expandafter#2\fi}
 
 \permanent\protected\def\doifelseallcommon{\syst_helpers_do_if_all_common_else\firstoftwoarguments\secondoftwoarguments}
-\permanent\protected\def\doifallcommon    {\syst_helpers_do_if_all_common_else\firstofonearguments\gobbleoneargument   }
-\permanent\protected\def\doifnotallcommon {\syst_helpers_do_if_all_common_else\gobbleoneargument  \firstofonearguments }
+\permanent\protected\def\doifallcommon    {\syst_helpers_do_if_all_common_else\firstofoneargument \gobbleoneargument   }
+\permanent\protected\def\doifnotallcommon {\syst_helpers_do_if_all_common_else\gobbleoneargument  \firstofoneargument  }
 
 \aliased\let\doifallcommonelse\doifelseallcommon
 
@@ -5534,9 +5534,9 @@
 %D
 %D \starttyping
 %D \def\dontleavehmode
-%D   {\ifhmode\else \ifmmode\else
+%D   {\ifhmode\orelse\ifmmode\else
 %D      {\mathsurround\zeropoint\everymath\emptytoks$ $}%
-%D    \fi \fi}
+%D    \fi}
 %D \stoptyping
 %D
 %D And finaly we got the following alternative, one that avoids interfering grouping
@@ -5546,9 +5546,9 @@
 %D \newbox\b_syst_helpers_dlh
 %D
 %D \protected\def\dontleavehmode
-%D   {\ifhmode\else \ifmmode\else
+%D   {\ifhmode\orelse\ifmmode\else
 %D      \setbox\b_syst_helpers_dlh\hbox{\mathsurround\zeropoint\everymath\emptytoks$ $}\unhbox\b_syst_helpers_dlh
-%D    \fi \fi}
+%D    \fi}
 %D \stoptyping
 %D
 %D But, as we run a recent version of \TEX, we can use the new primitive:
diff --git a/tex/context/base/mkxl/tabl-ltb.mkxl b/tex/context/base/mkxl/tabl-ltb.mkxl
index 7be5c42f4..ab9675927 100644
--- a/tex/context/base/mkxl/tabl-ltb.mkxl
+++ b/tex/context/base/mkxl/tabl-ltb.mkxl
@@ -169,10 +169,10 @@
      \fi
    \getrawnoflines\scratchdimen
    \global\c_tabl_lines_n_of_lines\noflines
-   \ifconditional\c_tabl_lines_preroll \else \ifnum\c_tabl_lines_n_of_lines<\plustwo
+   \ifconditional\c_tabl_lines_preroll\orelse\ifnum\c_tabl_lines_n_of_lines<\plustwo
      \page
      \tabl_lines_set
-   \fi \fi}
+   \fi}
 
 \def\tabl_lines_step_cell
   {\advance\scratchdimen\linetablecparameter\c!width
@@ -478,14 +478,14 @@
        \fi
        \global\d_tabl_lines_width\wd\b_tabl_lines_cell
        \tabl_lines_start_part
-       \ifscratchconditionone \else \ifcase\c_tabl_lines_repeat \else
+       \ifscratchconditionone \orelse \ifcase\c_tabl_lines_repeat \else
          % check for left/right page
          \ifcase\c_tabl_lines_page\donetrue\or\donetrue\or\donefalse\fi\ifdone
            % insert repeater
            \global\advance\d_tabl_lines_width\wd\tablebox\zerocount
            \ifconditional\c_tabl_lines_preroll\kern\wd\else\unhcopy\fi\tablebox\zerocount
          \fi
-       \fi \fi
+       \fi
      \fi
      \ifconditional\c_tabl_lines_preroll \else
        \box\b_tabl_lines_cell
@@ -535,9 +535,9 @@
    \global\c_tabl_lines_column\zerocount
    \global\c_tabl_lines_subcol\zerocount
    \global\d_tabl_lines_width\zeropoint
-   \ifconditional\c_tabl_lines_preroll \else \ifdim\pagetotal>\zeropoint
+   \ifconditional\c_tabl_lines_preroll\orelse\ifdim\pagetotal>\zeropoint
      \verticalstrut\kern-\struttotal
-   \fi \fi
+   \fi
    \tabl_lines_set
    \tabl_lines_check_page
    \enforced\let\BR\tabl_lines_BR
@@ -629,10 +629,10 @@
 
 \def\tabl_lines_check_page
   {\global\c_tabl_lines_page\zerocount
-   \ifcase\c_tabl_lines_repeat \else \ifcase\c_tabl_lines_page
+   \ifcase\c_tabl_lines_repeat\orelse\ifcase\c_tabl_lines_page
      \doif{\linetableparameter\c!repeat}\v!no
        {\global\c_tabl_lines_page\doifelseoddpage\plusone\plustwo}%
-   \fi \fi}
+   \fi}
 
 \def\tabl_lines_flush_head
   {\ifcase\c_tabl_lines_head_state
diff --git a/tex/context/base/mkxl/tabl-ntb.mkxl b/tex/context/base/mkxl/tabl-ntb.mkxl
index aa29237b5..2840a9cd1 100644
--- a/tex/context/base/mkxl/tabl-ntb.mkxl
+++ b/tex/context/base/mkxl/tabl-ntb.mkxl
@@ -77,8 +77,8 @@
 %D
 %D \typebuffer \getbuffer
 
-\ifdefined\dotagTABLEcell   \else \let\dotagTABLEcell  \relax \fi % todo: namespace
-\ifdefined\dotagTABLEsignal \else \let\dotagTABLEsignal\relax \fi % todo: namespace
+\ifdefined\dotagTABLEcell   \else \aliased\let\dotagTABLEcell  \relax \fi % todo: namespace
+\ifdefined\dotagTABLEsignal \else \aliased\let\dotagTABLEsignal\relax \fi % todo: namespace
 
 \let\tabl_ntb_next_level\relax
 
diff --git a/tex/context/base/mkxl/tabl-tbl.mkxl b/tex/context/base/mkxl/tabl-tbl.mkxl
index cacaef12c..d46eebe6a 100644
--- a/tex/context/base/mkxl/tabl-tbl.mkxl
+++ b/tex/context/base/mkxl/tabl-tbl.mkxl
@@ -219,15 +219,16 @@
 \newconstant     \c_tabl_tabulate_pass
 \newconstant     \c_tabl_tabulate_type
 \newconstant     \c_tabl_tabulate_kind % 1=strong  2=equals
-\newconstant     \c_tabl_tabulate_splitlinemode  \c_tabl_tabulate_splitlinemode\plusone
+\newconstant     \c_tabl_tabulate_splitlinemode    \c_tabl_tabulate_splitlinemode\plusone
 \newconstant     \c_tabl_tabulate_colorspan
 \newconstant     \c_tabl_tabulate_localcolorspan
 \newconstant     \c_tabl_tabulate_modus
 
-\let\tabulatesplitlinemode\c_tabl_tabulate_splitlinemode % temp hack, we need an interface
-
 \let             \m_tabl_tabulate_separator_factor \empty % fraction
 
+\aliased\let\tabulatesplitlinemode\c_tabl_tabulate_splitlinemode % temp hack, we need an interface
+
+
 \newtoks         \everytabulatepar           % where used ?
 \newtoks         \everytabulate              % public ?
 
@@ -342,8 +343,8 @@
 
 \let\tabl_tabulate_shaped_par_end\egroup
 
-\ifdefined\dotagtabulatecell   \else \let\dotagtabulatecell  \relax \fi
-\ifdefined\dotagtabulatesignal \else \let\dotagtabulatesignal\relax \fi
+\ifdefined\dotagtabulatecell   \else \aliased\let\dotagtabulatecell  \relax \fi
+\ifdefined\dotagtabulatesignal \else \aliased\let\dotagtabulatesignal\relax \fi
 
 \protected\def\tabl_tabulate_check_local_color_first#1#2%
   {\relax}
@@ -1328,7 +1329,7 @@
      \tabl_tabulate_insert_body
      \tabl_tabulate_process}
 
-\def\tabulateEQ
+\permanent\protected\def\tabulateEQ
   {\ifconditional\c_tabl_tabulate_firstflushed\else
      \dostarttaggedchained\t!ignore\empty\empty
      \dostarttagged\t!ignore\empty
@@ -1356,13 +1357,13 @@
 \let\m_tabl_tabulate_blank_default      \empty
 
 \appendtoks
-    \glet\m_tabl_tabulate_color_previous      \empty
-    \glet\m_tabl_tabulate_color               \empty
-    \glet\m_tabl_tabulate_text_color          \empty
-    \glet\m_tabl_tabulate_color_local         \empty
-    \glet\m_tabl_tabulate_vrule_color         \empty
-    \glet\m_tabl_tabulate_vrule_color_local   \empty
-    \global    \d_tabl_tabulate_vrulethickness_local\zeropoint
+    \glet  \m_tabl_tabulate_color_previous      \empty
+    \glet  \m_tabl_tabulate_color               \empty
+    \glet  \m_tabl_tabulate_text_color          \empty
+    \glet  \m_tabl_tabulate_color_local         \empty
+    \glet  \m_tabl_tabulate_vrule_color         \empty
+    \glet  \m_tabl_tabulate_vrule_color_local   \empty
+    \global\d_tabl_tabulate_vrulethickness_local\zeropoint
 \to \t_tabl_tabulate_every_row
 
 \protected\def\tabl_tabulate_color_side_right_second
@@ -2296,7 +2297,7 @@
    \dostarttagged\t!tabulaterow\empty
    \setfalse\inhibitmargindata % new per 2012.06.13 ... really needed
 %  % \everycr\expandafter{\the\everycr\noalign{\the\t_tabl_tabulate_every_real_row}\dostoptagged\dostarttagged\t!tabulaterow\empty}%
-%    \toksapp\everycr{\noalign{\the\t_tabl_tabulate_every_real_row\dostoptagged\dostarttagged\t!tabulaterow\empty}}%
+   \toksapp\everycr{\noalign{\the\t_tabl_tabulate_every_real_row\dostoptagged\dostarttagged\t!tabulaterow\empty}}%
    \expandafter\halign\expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}%
    \dostoptagged
    \dostoptagged
diff --git a/tex/context/base/mkxl/tabl-tsp.mkxl b/tex/context/base/mkxl/tabl-tsp.mkxl
index 561ed73cb..9d4a13380 100644
--- a/tex/context/base/mkxl/tabl-tsp.mkxl
+++ b/tex/context/base/mkxl/tabl-tsp.mkxl
@@ -74,8 +74,8 @@
 \newcount      \noffloatssplits
 \newtoks       \everysplitfloatsetup
 
-\let           \extrasplitfloatlines \!!zerocount
-\let           \splitfloatfinalizer  \relax
+\mutable\let   \extrasplitfloatlines \!!zerocount
+\mutable\let   \splitfloatfinalizer  \relax
 
 \mutable\let   \floatcaptionsuffix   \empty
 
diff --git a/tex/context/base/mkxl/tabl-xtb.mklx b/tex/context/base/mkxl/tabl-xtb.mklx
index ae763dd52..b15d99c12 100644
--- a/tex/context/base/mkxl/tabl-xtb.mklx
+++ b/tex/context/base/mkxl/tabl-xtb.mklx
@@ -410,7 +410,7 @@
 %
 % \let\xtablesplitstate\c_tabl_x_state
 
-\let\extratxtablesplitheight\zeropoint % might disappear so don't depend on it
+\mutable\let\extraxtablesplitheight\zeropoint % might disappear so don't depend on it
 
 \protected\def\tabl_x_flush_float_normal
   {\clf_x_table_flush
@@ -420,7 +420,7 @@
 \protected\def\tabl_x_flush_float_split
   {\resetdirecttsplit
    \edef\extrasplitfloatlines{\xtableparameter\c!split}%
-   \d_split_minimum_free_space\dimexpr\extratxtablesplitheight+\xtableparameter\c!splitoffset\relax
+   \d_split_minimum_free_space\dimexpr\extraxtablesplitheight+\xtableparameter\c!splitoffset\relax
   %\c_split_minimum_free_lines\plustwo % not needed here as we're precise enough
    \let\tsplitdirectsplitter\tabl_x_split_splitter
    \let\tsplitdirectwidth   \d_tabl_x_final_width
diff --git a/tex/context/base/mkxl/trac-vis.lmt b/tex/context/base/mkxl/trac-vis.lmt
index 96f3215f7..29cdbaeda 100644
--- a/tex/context/base/mkxl/trac-vis.lmt
+++ b/tex/context/base/mkxl/trac-vis.lmt
@@ -37,9 +37,7 @@ local tonut               = nuts.tonut
 
 local setboth             = nuts.setboth
 local setlink             = nuts.setlink
-local setdisc             = nuts.setdisc
 local setlist             = nuts.setlist
-local setleader           = nuts.setleader
 local setsubtype          = nuts.setsubtype
 local setattr             = nuts.setattr
 local setwidth            = nuts.setwidth
@@ -51,18 +49,13 @@ local getattr             = nuts.getattr
 local getsubtype          = nuts.getsubtype
 local getbox              = nuts.getbox
 local getlist             = nuts.getlist
-local getleader           = nuts.getleader
 local getnext             = nuts.getnext
 local getboth             = nuts.getboth
-local getdisc             = nuts.getdisc
 local getwhd              = nuts.getwhd
 local getkern             = nuts.getkern
-local getpenalty          = nuts.getpenalty
 local getwidth            = nuts.getwidth
 local getdepth            = nuts.getdepth
-local getshift            = nuts.getshift
 local getexpansion        = nuts.getexpansion
-local getdirection        = nuts.getdirection
 local getstate            = nuts.getstate
 
 local isglyph             = nuts.isglyph
@@ -75,7 +68,6 @@ local flush_node_list     = nuts.flush_list
 local insert_node_before  = nuts.insert_before
 local insert_node_after   = nuts.insert_after
 local apply_to_nodes      = nuts.apply
-local effectiveglue       = nuts.effective_glue
 
 local hpack_string        = nuts.typesetters.tohpack
 
@@ -185,9 +177,9 @@ local preset_all    = preset_makeup
                     + modes.dir + modes.whatsit
 
 function visualizers.setfont(id)
-    usedfont = id or current_font()
-    exheight = exheights[usedfont]
-    emwidth  = emwidths[usedfont]
+    usedfont  = id or current_font()
+    exheight  = exheights[usedfont]
+    emwidth   = emwidths[usedfont]
 end
 
 -- we can preset a bunch of bits
@@ -373,7 +365,8 @@ for mode, value in next, modes do
     trackers.register(formatters["visualizers.%s"](mode), function(v) set(mode,v) end)
 end
 
-local fraction = 10
+local fraction  = 10
+local normalize = true
 
 trackers  .register("visualizers.reset",    function(v) set("reset", v) end)
 trackers  .register("visualizers.all",      function(v) set("all",   v) end)
@@ -417,7 +410,9 @@ local c_discretionary_d = "trace:dd"
 ----- c_depth_d         = "trace:do"
 ----- c_indent_d        = "trace:ds"
 
-local function sometext(str,layer,color,textcolor,lap) -- we can just paste verbatim together .. no typesteting needed
+-- we can just paste verbatim together .. no typesetting needed
+
+local function sometext(str,layer,color,textcolor,lap,variant)
     local text = hpack_string(str,usedfont)
     local size = getwidth(text)
     local rule = new_rule(size,2*exheight,exheight/2)
@@ -432,6 +427,9 @@ local function sometext(str,layer,color,textcolor,lap) -- we can just paste verb
     setlisttransparency(info,c_zero)
     info = hpack_nodes(info)
     local width = getwidth(info)
+    if variant then
+        nuts.setoffsets(info,0,variant*exheight)
+    end
     if lap then
         info = new_hlist(setlink(new_kern(-width),info))
     else
@@ -627,14 +625,16 @@ end
 
 local dir, par do
 
-    local dircodes    = nodes.dircodes
-    local dirvalues   = nodes.dirvalues
+    local dircodes     = nodes.dircodes
+    local dirvalues    = nodes.dirvalues
 
-    local cancel_code = dircodes.cancel
-    local l2r_code    = dirvalues.l2r
-    local r2l_code    = dirvalues.r2l
+    local cancel_code  = dircodes.cancel
+    local l2r_code     = dirvalues.l2r
+    local r2l_code     = dirvalues.r2l
 
-    local d_cache     = caches["dir"]
+    local d_cache      = caches["dir"]
+
+    local getdirection = nuts.getdirection
 
     local tags = {
         l2r    = "L2R",
@@ -757,6 +757,8 @@ local ruledbox do
     local b_cache = caches["box"]
     local o_cache = caches["origin"]
 
+    local getshift = nuts.getshift
+
     setmetatableindex(o_cache,function(t,size)
         local rule   = new_rule(2*size,size,size)
         local origin = hpack_nodes(rule)
@@ -927,6 +929,8 @@ end
 
 local ruledglue do
 
+    local effectiveglue         = nuts.effective_glue
+
     local gluecodes             = nodes.gluecodes
 
     local userskip_code         = gluecodes.userskip
@@ -943,8 +947,16 @@ local ruledglue do
     local indentskip_code       = gluecodes.indentskip
     local correctionskip_code   = gluecodes.correctionskip
 
-    local g_cache_v = caches["vglue"]
-    local g_cache_h = caches["hglue"]
+    local g_cache_v  = caches["vglue"]
+    local g_cache_h  = caches["hglue"]
+    local g_cache_ls = caches["leftskip"]
+    local g_cache_rs = caches["rightskip"]
+    local g_cache_lh = caches["lefthang"]
+    local g_cache_rh = caches["righthang"]
+    local g_cache_lp = caches["parfillleftskip"]
+    local g_cache_rp = caches["parfillrightskip"]
+    local g_cache_is = caches["indentskip"]
+    local g_cache_cs = caches["correctionskip"]
 
     local tags = {
      -- [userskip_code]                   = "US",
@@ -983,11 +995,21 @@ local ruledglue do
         [correctionskip_code]             = "CS",
     }
 
+    local stags = {
+        [lefthangskip_code]     =  0.5,
+        [righthangskip_code]    =  0.5,
+        [leftskip_code]         = -2,
+        [rightskip_code]        = -2,
+        [parfillleftskip_code]  = -0.75,
+        [parfillrightskip_code] = -0.75,
+    }
+
     -- we sometimes pass previous as we can have issues in math (not watertight for all)
 
     ruledglue = function(head,current,vertical,parent)
         local subtype = getsubtype(current)
         local width   = effectiveglue(current,parent)
+        local stag    = normalize and stags[subtype]
         local amount  = formatters["%s:%0.3f"](tags[subtype] or (vertical and "VS") or "HS",width*pt_factor)
         local info    = (vertical and g_cache_v or g_cache_h)[amount]
         if info then
@@ -995,12 +1017,6 @@ local ruledglue do
         else
             if subtype == spaceskip_code or subtype == xspaceskip_code or subtype == zerospaceskip_code then
                 info = sometext(amount,l_glue,c_space)
-            elseif subtype == leftskip_code or subtype == rightskip_code then
-                info = sometext(amount,l_glue,c_skip_a)
-            elseif subtype == lefthangskip_code or subtype == righthangskip_code then
-                info = sometext(amount,l_glue,c_skip_b)
-            elseif subtype == parfillleftskip_code or subtype == parfillrightskip_code or subtype == indentskip_code or subtype == correctionskip_code then
-                info = sometext(amount,l_glue,c_indent)
             elseif subtype == userskip_code then
                 if width > 0 then
                     info = sometext(amount,l_glue,c_positive)
@@ -1009,11 +1025,26 @@ local ruledglue do
                 else
                     info = sometext(amount,l_glue,c_zero)
                 end
+            elseif subtype == indentskip_code or subtype == correctionskip_code then
+                info = sometext(amount,l_glue,c_indent)
+            elseif subtype == leftskip_code then
+                info = sometext(amount,l_glue,normalize and c_space or c_skip_a,false,true,stag)
+            elseif subtype == rightskip_code then
+                info = sometext(amount,l_glue,normalize and c_space or c_skip_a,false,false,stag)
+            elseif subtype == lefthangskip_code then
+                info = sometext(amount,l_glue,normalize and c_space or c_skip_b,false,true,stag)
+            elseif subtype == righthangskip_code then
+                info = sometext(amount,l_glue,normalize and c_space or c_skip_b,false,false,stag)
+            elseif subtype == parfillleftskip_code then
+                info = sometext(amount,l_glue,c_indent,false,true,stag)
+            elseif subtype == parfillrightskip_code then
+                info = sometext(amount,l_glue,c_indent,false,false,stag)
             else
                 info = sometext(amount,l_glue,c_skip_b)
             end
             (vertical and g_cache_v or g_cache_h)[amount] = info
         end
+      ::PICKIP::
         info = copy_list(info)
         if vertical then
             info = vpack_nodes(info)
@@ -1207,6 +1238,8 @@ local ruledpenalty do
 
     local raisepenalties = false
 
+    local getpenalty     = nuts.getpenalty
+
     directives.register("visualizers.raisepenalties",function(v) raisepenalties = v end)
 
     ruledpenalty = function(head,current,vertical)
@@ -1267,6 +1300,12 @@ do
 
     local vtop_package_state   = 3 -- todo: symbolic
 
+    local getleader            = nuts.getleader
+    local getdisc              = nuts.getdisc
+
+    local setleader            = nuts.setleader
+    local setdisc              = nuts.setdisc
+
     local cache
 
     local function visualize(head,vertical,forced,parent)
diff --git a/tex/context/base/mkxl/type-ini.mklx b/tex/context/base/mkxl/type-ini.mklx
index 95587c493..fa616e0f7 100644
--- a/tex/context/base/mkxl/type-ini.mklx
+++ b/tex/context/base/mkxl/type-ini.mklx
@@ -82,8 +82,8 @@
 
 % tricky ... here we push/pop ... so \let
 
-\let\typescriptmethod\plusone % 1: empty==all==true  2: empty==false
-\let\typescriptstate \plustwo % 1: process 2: store
+\mutable\let\typescriptmethod\plusone % 1: empty==all==true  2: empty==false
+\mutable\let\typescriptstate \plustwo % 1: process 2: store
 
 \installmacrostack\typescriptmethod
 \installmacrostack\typescriptstate
diff --git a/tex/context/base/mkxl/typo-del.mkxl b/tex/context/base/mkxl/typo-del.mkxl
index 13f525f69..ad0c93fa0 100644
--- a/tex/context/base/mkxl/typo-del.mkxl
+++ b/tex/context/base/mkxl/typo-del.mkxl
@@ -17,8 +17,8 @@
 
 \unprotect
 
-\ifdefined\dotagsetdelimitedsymbol   \else \let\dotagsetdelimitedsymbol  \gobbleoneargument \fi
-\ifdefined\dotagsetsubsentencesymbol \else \let\dotagsetsubsentencesymbol\gobbleoneargument \fi
+\ifdefined\dotagsetdelimitedsymbol   \else \aliased\let\dotagsetdelimitedsymbol  \gobbleoneargument \fi
+\ifdefined\dotagsetsubsentencesymbol \else \aliased\let\dotagsetsubsentencesymbol\gobbleoneargument \fi
 
 % THIS IS OBSOLETE:
 
diff --git a/tex/context/base/mkxl/typo-mar.mkxl b/tex/context/base/mkxl/typo-mar.mkxl
index 1fd904cc3..3b9b99a28 100644
--- a/tex/context/base/mkxl/typo-mar.mkxl
+++ b/tex/context/base/mkxl/typo-mar.mkxl
@@ -164,8 +164,8 @@
 \newcount\nofmargintexts
 \newcount\c_typo_margins_n
 
-\ifdefined\dotagmarginanchor \else \let\dotagmarginanchor\gobbleoneargument \fi
-\ifdefined\dotagmargintext   \else \let\dotagmargintext  \gobbleoneargument \fi
+\ifdefined\dotagmarginanchor \else \aliased\let\dotagmarginanchor\gobbleoneargument \fi
+\ifdefined\dotagmargintext   \else \aliased\let\dotagmargintext  \gobbleoneargument \fi
 
 \definepagestate[\s!margintext]
 
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index f4e9fbcca..a90920888 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
 -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
 -- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date  : 2020-11-28 13:15
+-- merge date  : 2020-11-30 10:20
 
 do -- begin closure to overcome local limits and interference
 
-- 
cgit v1.2.3