From 809177a0640771ac59eb13a1b52c91acb644e3a1 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Sat, 10 Sep 2022 03:48:41 +0200
Subject: 2022-09-10 02:44:00

---
 tex/context/base/mkii/cont-new.mkii                |   2 +-
 tex/context/base/mkii/context.mkii                 |   2 +-
 tex/context/base/mkii/mult-de.mkii                 |  12 +-
 tex/context/base/mkii/mult-it.mkii                 |   4 +-
 tex/context/base/mkii/mult-ro.mkii                 |   4 +-
 tex/context/base/mkiv/char-def.lua                 |   1 +
 tex/context/base/mkiv/cont-new.mkiv                |   2 +-
 tex/context/base/mkiv/context.mkiv                 |   2 +-
 tex/context/base/mkiv/font-prv.lua                 |   2 +
 tex/context/base/mkiv/math-ini.mkiv                |  18 +-
 tex/context/base/mkiv/mult-def.lua                 |  16 +-
 tex/context/base/mkiv/mult-low.lua                 |   4 +-
 tex/context/base/mkiv/mult-prm.lua                 |  33 +-
 tex/context/base/mkiv/status-files.pdf             | Bin 24618 -> 24651 bytes
 tex/context/base/mkiv/status-lua.pdf               | Bin 259899 -> 260450 bytes
 tex/context/base/mkiv/util-tab.lua                 |  22 +
 tex/context/base/mkxl/catc-ini.mkxl                |  28 +-
 tex/context/base/mkxl/char-prv.lmt                 |  34 -
 tex/context/base/mkxl/cont-new.mkxl                |   2 +-
 tex/context/base/mkxl/context.mkxl                 |   2 +-
 tex/context/base/mkxl/core-con.mkxl                |   2 +-
 tex/context/base/mkxl/driv-shp.lmt                 |   2 +
 tex/context/base/mkxl/font-ots.lmt                 |  12 +-
 tex/context/base/mkxl/lang-mis.mkxl                |  10 +-
 tex/context/base/mkxl/lpdf-lmt.lmt                 |   2 +
 tex/context/base/mkxl/luat-log.lmt                 |  28 +-
 tex/context/base/mkxl/math-act.lmt                 |  50 +-
 tex/context/base/mkxl/math-ali.lmt                 | 327 ++++++++--
 tex/context/base/mkxl/math-ali.mkxl                |  55 ++
 tex/context/base/mkxl/math-def.mkxl                |  10 +-
 tex/context/base/mkxl/math-del.mklx                |  32 +-
 tex/context/base/mkxl/math-fen.mkxl                |  23 +-
 tex/context/base/mkxl/math-ini.lmt                 |   1 +
 tex/context/base/mkxl/math-ini.mkxl                | 367 ++++++++---
 tex/context/base/mkxl/math-noa.lmt                 | 689 ++++++++++++---------
 tex/context/base/mkxl/math-rad.mklx                |  13 +-
 tex/context/base/mkxl/node-nut.lmt                 |   5 +
 tex/context/base/mkxl/node-res.lmt                 |  12 +-
 tex/context/base/mkxl/node-rul.mkxl                |   6 +-
 tex/context/base/mkxl/node-shp.lmt                 |   8 +-
 tex/context/base/mkxl/pack-box.mkxl                |  48 +-
 tex/context/base/mkxl/task-ini.lmt                 |   4 +-
 tex/context/base/mkxl/typo-cap.lmt                 |   2 +-
 tex/context/base/mkxl/typo-itc.lmt                 |  90 ++-
 tex/context/base/mkxl/typo-rub.lmt                 | 202 ++++--
 tex/context/fonts/mkiv/pagella-math.lfg            |  12 +
 tex/context/interface/mkii/keys-de.xml             |  12 +-
 tex/context/interface/mkii/keys-it.xml             |   4 +-
 tex/context/interface/mkii/keys-ro.xml             |   4 +-
 tex/context/modules/mkiv/s-abbreviations-logos.tex |   1 +
 tex/context/modules/mkxl/m-gimmicks.mkxl           |  25 +-
 tex/generic/context/luatex/luatex-fonts-merged.lua |   2 +-
 52 files changed, 1524 insertions(+), 726 deletions(-)

(limited to 'tex')

diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 8b4de2c7c..82a268348 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{2022.08.25 19:18}
+\newcontextversion{2022.09.10 02:42}
 
 %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 376318c3d..f2ca9aba1 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{2022.08.25 19:18}
+\edef\contextversion{2022.09.10 02:42}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii
index 8537c66cd..cd526730e 100644
--- a/tex/context/base/mkii/mult-de.mkii
+++ b/tex/context/base/mkii/mult-de.mkii
@@ -93,7 +93,6 @@
 \setinterfacevariable{author}{autor}
 \setinterfacevariable{auto}{auto}
 \setinterfacevariable{autointro}{autointro}
-\setinterfacevariable{autopunctuation}{autopunctuation}
 \setinterfacevariable{back}{zurueck}
 \setinterfacevariable{background}{hintergrund}
 \setinterfacevariable{backmatter}{epiloge}
@@ -680,6 +679,9 @@
 \setinterfaceconstant{autofile}{autofile}
 \setinterfaceconstant{autofocus}{autofocus}
 \setinterfaceconstant{autohang}{autohang}
+\setinterfaceconstant{autonumbers}{autonumbers}
+\setinterfaceconstant{autopunctuation}{autopunctuation}
+\setinterfaceconstant{autospacing}{autospacing}
 \setinterfaceconstant{autostrut}{autostrut}
 \setinterfaceconstant{autowidth}{autobreite}
 \setinterfaceconstant{availableheight}{availableheight}
@@ -870,6 +872,7 @@
 \setinterfaceconstant{frameradius}{rahmenradius}
 \setinterfaceconstant{frames}{umrahmen}
 \setinterfaceconstant{freeregion}{freeregion}
+\setinterfaceconstant{freezespacing}{freezespacing}
 \setinterfaceconstant{from}{von}
 \setinterfaceconstant{functioncolor}{functioncolor}
 \setinterfaceconstant{functionstyle}{functionstyle}
@@ -950,6 +953,7 @@
 \setinterfaceconstant{lastpubsep}{lastpubsep}
 \setinterfaceconstant{layout}{layout}
 \setinterfaceconstant{left}{links}
+\setinterfaceconstant{leftclass}{leftclass}
 \setinterfaceconstant{leftcolor}{linkerfarbe}
 \setinterfaceconstant{leftcompoundhyphen}{leftcompoundhyphen}
 \setinterfaceconstant{leftedge}{linkekante}
@@ -1008,6 +1012,7 @@
 \setinterfaceconstant{menu}{menue}
 \setinterfaceconstant{method}{methode}
 \setinterfaceconstant{middle}{mittig}
+\setinterfaceconstant{middleclass}{middleclass}
 \setinterfaceconstant{middlecolor}{middlecolor}
 \setinterfaceconstant{middlecommand}{middlecommand}
 \setinterfaceconstant{middlesource}{middlesource}
@@ -1054,6 +1059,8 @@
 \setinterfaceconstant{numberconversionset}{numberconversionset}
 \setinterfaceconstant{numberdistance}{numberdistance}
 \setinterfaceconstant{numbering}{nummerierung}
+\setinterfaceconstant{numberlocation}{numberlocation}
+\setinterfaceconstant{numbermethod}{numbermethod}
 \setinterfaceconstant{numberorder}{numberorder}
 \setinterfaceconstant{numberprefix}{numberprefix}
 \setinterfaceconstant{numbersegments}{numbersegments}
@@ -1064,6 +1071,7 @@
 \setinterfaceconstant{numberstopper}{numberstopper}
 \setinterfaceconstant{numberstrut}{numberstrut}
 \setinterfaceconstant{numberstyle}{nummernstil}
+\setinterfaceconstant{numberthreshold}{numberthreshold}
 \setinterfaceconstant{numberwidth}{numberwidth}
 \setinterfaceconstant{nx}{nx}
 \setinterfaceconstant{ny}{ny}
@@ -1117,6 +1125,7 @@
 \setinterfaceconstant{palet}{palette}
 \setinterfaceconstant{paper}{papier}
 \setinterfaceconstant{paragraph}{absatz}
+\setinterfaceconstant{penalties}{penalties}
 \setinterfaceconstant{period}{period}
 \setinterfaceconstant{place}{platziere}
 \setinterfaceconstant{placehead}{setzekopf}
@@ -1170,6 +1179,7 @@
 \setinterfaceconstant{reverse}{reverse}
 \setinterfaceconstant{right}{rechts}
 \setinterfaceconstant{rightchars}{rightchars}
+\setinterfaceconstant{rightclass}{rightclass}
 \setinterfaceconstant{rightcolor}{rechterfarbe}
 \setinterfaceconstant{rightcompoundhyphen}{rightcompoundhyphen}
 \setinterfaceconstant{rightedge}{rechtekante}
diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii
index 6541e8db4..18840146a 100644
--- a/tex/context/base/mkii/mult-it.mkii
+++ b/tex/context/base/mkii/mult-it.mkii
@@ -93,7 +93,6 @@
 \setinterfacevariable{author}{autore}
 \setinterfacevariable{auto}{auto}
 \setinterfacevariable{autointro}{autointro}
-\setinterfacevariable{autopunctuation}{autopunctuation}
 \setinterfacevariable{back}{dietro}
 \setinterfacevariable{background}{sfondo}
 \setinterfacevariable{backmatter}{postambolo}
@@ -680,6 +679,9 @@
 \setinterfaceconstant{autofile}{autofile}
 \setinterfaceconstant{autofocus}{autofocus}
 \setinterfaceconstant{autohang}{autohang}
+\setinterfaceconstant{autonumbers}{autonumbers}
+\setinterfaceconstant{autopunctuation}{autopunctuation}
+\setinterfaceconstant{autospacing}{autospacing}
 \setinterfaceconstant{autostrut}{autostrut}
 \setinterfaceconstant{autowidth}{autoampiezza}
 \setinterfaceconstant{availableheight}{availableheight}
diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii
index 79c0349ea..e35ebac50 100644
--- a/tex/context/base/mkii/mult-ro.mkii
+++ b/tex/context/base/mkii/mult-ro.mkii
@@ -93,7 +93,6 @@
 \setinterfacevariable{author}{autor}
 \setinterfacevariable{auto}{auto}
 \setinterfacevariable{autointro}{autointro}
-\setinterfacevariable{autopunctuation}{autopunctuation}
 \setinterfacevariable{back}{inapot}
 \setinterfacevariable{background}{fundal}
 \setinterfacevariable{backmatter}{epilogul}
@@ -680,6 +679,9 @@
 \setinterfaceconstant{autofile}{autofile}
 \setinterfaceconstant{autofocus}{autofocus}
 \setinterfaceconstant{autohang}{autohang}
+\setinterfaceconstant{autonumbers}{autonumbers}
+\setinterfaceconstant{autopunctuation}{autopunctuation}
+\setinterfaceconstant{autospacing}{autospacing}
 \setinterfaceconstant{autostrut}{autostrut}
 \setinterfaceconstant{autowidth}{autolatime}
 \setinterfaceconstant{availableheight}{availableheight}
diff --git a/tex/context/base/mkiv/char-def.lua b/tex/context/base/mkiv/char-def.lua
index 5325dc06e..1701aeb3b 100644
--- a/tex/context/base/mkiv/char-def.lua
+++ b/tex/context/base/mkiv/char-def.lua
@@ -655,6 +655,7 @@ characters.data={
   direction="cs",
   linebreak="is",
   mathclass="relation",
+--mathsymbol=0x2236,
   unicodeslot=0x3A,
  },
  {
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 49e307f12..3ce44cab3 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{2022.08.25 19:18}
+\newcontextversion{2022.09.10 02:42}
 
 %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 edc4989ad..12f23d73f 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -49,7 +49,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2022.08.25 19:18}
+\edef\contextversion{2022.09.10 02:42}
 
 %D Kind of special:
 
diff --git a/tex/context/base/mkiv/font-prv.lua b/tex/context/base/mkiv/font-prv.lua
index 15057e255..e613eb7d3 100644
--- a/tex/context/base/mkiv/font-prv.lua
+++ b/tex/context/base/mkiv/font-prv.lua
@@ -39,6 +39,8 @@ local sharedprivates = setmetatableindex(function(t,k)
     return v
 end)
 
+fonts.helpers.sharedprivates = sharedprivates
+
 function helpers.addprivate(tfmdata,name,characterdata)
     local properties = tfmdata.properties
     local characters = tfmdata.characters
diff --git a/tex/context/base/mkiv/math-ini.mkiv b/tex/context/base/mkiv/math-ini.mkiv
index 80a9f1412..94b50c12a 100644
--- a/tex/context/base/mkiv/math-ini.mkiv
+++ b/tex/context/base/mkiv/math-ini.mkiv
@@ -1586,11 +1586,11 @@
 % \unexpanded\def\disablemathpunctuation{\setfalse\automathpunctuation}
 %
 % \appendtoks
-%     \doifelse{\mathematicsparameter\v!autopunctuation}\v!yes\settrue\setfalse\automathpunctuation
+%     \doifelse{\mathematicsparameter\c!autopunctuation}\v!yes\settrue\setfalse\automathpunctuation
 % \to \everyswitchmathematics
 %
 % \setupmathematics
-%   [\v!autopunctuation=\v!no]
+%   [\c!autopunctuation=\v!no]
 %
 % \def\math_punctuation_next{\ifx\nexttoken\blankspace\signalcharacter\fi}
 %
@@ -1676,9 +1676,9 @@
            \let\math_punctuation_yes_period   \math_punctuation_nop_period
            \let\math_punctuation_yes_semicolon\math_punctuation_all_semicolon
 
-\def\math_punctuation_comma_next    {\begingroup\Umathcode\c_math_comma    \ifx\nexttoken\blankspace\mathordcode\else\mathordcode\fi\zerocount\c_math_comma    ,\endgroup}
-\def\math_punctuation_period_next   {\begingroup\Umathcode\c_math_period   \ifx\nexttoken\blankspace\mathordcode\else\mathordcode\fi\zerocount\c_math_period   .\endgroup}
-\def\math_punctuation_semicolon_next{\begingroup\Umathcode\c_math_semicolon\ifx\nexttoken\blankspace\mathordcode\else\mathordcode\fi\zerocount\c_math_semicolon;\endgroup}
+\def\math_punctuation_comma_next    {\begingroup\Umathcode\c_math_comma    \ifx\nexttoken\blankspace\mathpunctcode\else\mathordcode\fi\zerocount\c_math_comma    ,\endgroup}
+\def\math_punctuation_period_next   {\begingroup\Umathcode\c_math_period   \ifx\nexttoken\blankspace\mathpunctcode\else\mathordcode\fi\zerocount\c_math_period   .\endgroup}
+\def\math_punctuation_semicolon_next{\begingroup\Umathcode\c_math_semicolon\ifx\nexttoken\blankspace\mathpunctcode\else\mathordcode\fi\zerocount\c_math_semicolon;\endgroup}
 
 \installcorenamespace {mathautopunctuation}
 
@@ -1745,12 +1745,12 @@
     \mathcode\c_math_comma    \c_math_special
     \mathcode\c_math_period   \c_math_special
     \mathcode\c_math_semicolon\c_math_special
-    \begincsname\??mathautopunctuation\mathematicsparameter\v!autopunctuation\endcsname
+    \begincsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname
 \to \everymathematics
 
 \appendtoks
-    \ifcsname\??mathautopunctuation\mathematicsparameter\v!autopunctuation\endcsname \else
-        \letmathematicsparameter\v!autopunctuation\v!no
+    \ifcsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname \else
+        \letmathematicsparameter\c!autopunctuation\v!no
     \fi
 \to \everysetupmathematics
 
@@ -1758,7 +1758,7 @@
 \def\disablemathpunctuation{\csname\??mathautopunctuation\v!yes\endcsname}
 
 \setupmathematics
-  [\v!autopunctuation=\v!no] % no | yes | all | comma | yes,semicolon | all,semicolon
+  [\c!autopunctuation=\v!no] % no | yes | all | comma | yes,semicolon | all,semicolon
 
 %D The consequences of setting this are as follows:
 %D
diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua
index 56c7944f4..ca465b8c8 100644
--- a/tex/context/base/mkiv/mult-def.lua
+++ b/tex/context/base/mkiv/mult-def.lua
@@ -7628,6 +7628,18 @@ return {
    ["pe"]="عرض‌خودکار",
    ["ro"]="autolatime",
   },
+  ["autopunctuation"]={
+   ["en"]="autopunctuation",
+   ["fr"]="autoponctuation",
+  },
+  ["autospacing"]={
+   ["en"]="autospacing",
+   ["fr"]="autospacing",
+  },
+  ["autonumbers"]={
+   ["en"]="autonumbers",
+   ["fr"]="autonumbers",
+  },
   ["availableheight"]={
    ["en"]="availableheight",
    ["fr"]="hauteurdisponible",
@@ -14768,10 +14780,6 @@ return {
    ["pe"]="پیشگفتارخودکار",
    ["ro"]="autointro",
   },
-  ["autopunctuation"]={
-   ["en"]="autopunctuation",
-   ["fr"]="autoponctuation",
-  },
   ["back"]={
    ["cs"]="zpet",
    ["de"]="zurueck",
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index 62af2940a..e8ce240f0 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -173,7 +173,7 @@ return {
      -- "mathtopaccentcode", "mathbottomaccentcode", "mathdelimitercode", "mathrootcode", "mathprintcode",        --
         "mathalphacode", "mathboxcode", "mathchoicecode", "mathnothingcode", "mathlimopcode", "mathnolopcode",
         "mathunsetcode", "mathunspacedcode", "mathallcode", "mathfakecode", "mathunarycode",
-        "mathmaybeordinarycode", "mathmayberelationcode", "mathmaybebinarycode",
+        "mathmaybeordinarycode", "mathmayberelationcode", "mathmaybebinarycode", "mathnumbergroupcode",
         --
         "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument",
         --
@@ -216,7 +216,7 @@ return {
         "checkligatureclassoptioncode", "checkitaliccorrectionclassoptioncode", "checkkernpairclassoptioncode",
         "flattenclassoptioncode", "omitpenaltyclassoptioncode", "unpackclassoptioncode", "raiseprimeclassoptioncode",
         "carryoverlefttopkernclassoptioncode", "carryoverleftbottomkernclassoptioncode", "carryoverrighttopkernclassoptioncode", "carryoverrightbottomkernclassoptioncode",
-        "preferdelimiterdimensionsclassoptioncode", "autoinjectclassoptioncode",
+        "preferdelimiterdimensionsclassoptioncode", "autoinjectclassoptioncode", "removeitaliccorrectionclassoptioncode",
         --
         "noligaturingglyphoptioncode", "nokerningglyphoptioncode", "noleftligatureglyphoptioncode",
         "noleftkernglyphoptioncode", "norightligatureglyphoptioncode", "norightkernglyphoptioncode",
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index b0ba0dda7..546b93af3 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -69,7 +69,7 @@ return {
   "Uatopwithdelims",
   "Uchar",
   "Udelcode",
-  "Udelcodenum",
+  "Udelimited",
   "Udelimiter",
   "Udelimiterover",
   "Udelimiterunder",
@@ -80,6 +80,7 @@ return {
   "Umathaccentbaseheight",
   "Umathaccentbottomovershoot",
   "Umathaccentbottomshiftdown",
+  "Umathaccentextendmargin",
   "Umathaccentsuperscriptdrop",
   "Umathaccentsuperscriptpercent",
   "Umathaccenttopovershoot",
@@ -88,17 +89,14 @@ return {
   "Umathadapttoleft",
   "Umathadapttoright",
   "Umathaxis",
-  "Umathbotaccentvariant",
+  "Umathbottomaccentvariant",
   "Umathchar",
   "Umathcharclass",
   "Umathchardef",
   "Umathcharfam",
-  "Umathcharnum",
-  "Umathcharnumdef",
   "Umathcharslot",
   "Umathclass",
   "Umathcode",
-  "Umathcodenum",
   "Umathconnectoroverlapmin",
   "Umathdegreevariant",
   "Umathdelimiterovervariant",
@@ -221,6 +219,7 @@ return {
   "Uradical",
   "Uright",
   "Uroot",
+  "Urooted",
   "Ushiftedsubprescript",
   "Ushiftedsubscript",
   "Ushiftedsuperprescript",
@@ -250,6 +249,7 @@ return {
   "afterassigned",
   "aftergrouped",
   "aliased",
+  "aligncontent",
   "alignmark",
   "alignmentcellsource",
   "alignmentwrapsource",
@@ -340,6 +340,7 @@ return {
   "fontmathcontrol",
   "fontspecdef",
   "fontspecid",
+  "fontspecifiedname",
   "fontspecifiedsize",
   "fontspecscale",
   "fontspecxscale",
@@ -358,6 +359,7 @@ return {
   "gletcsname",
   "glettonothing",
   "gluespecdef",
+  "glyph",
   "glyphdatafield",
   "glyphoptions",
   "glyphscale",
@@ -377,6 +379,7 @@ return {
   "hccode",
   "hjcode",
   "hmcode",
+  "holdingmigrations",
   "hpack",
   "hyphenationmin",
   "hyphenationmode",
@@ -522,6 +525,9 @@ return {
   "mathsurroundmode",
   "mathsurroundskip",
   "maththreshold",
+  "meaningasis",
+  "meaningfull",
+  "meaningless",
   "mugluespecdef",
   "mutable",
   "noaligned",
@@ -542,6 +548,7 @@ return {
   "outputbox",
   "overloaded",
   "overloadmode",
+  "overshoot",
   "pageboundary",
   "pageextragoal",
   "pagevsize",
@@ -573,6 +580,7 @@ return {
   "scaledemwidth",
   "scaledexheight",
   "scaledextraspace",
+  "scaledfontdimen",
   "scaledinterwordshrink",
   "scaledinterwordspace",
   "scaledinterwordstretch",
@@ -595,6 +603,7 @@ return {
   "shapingpenaltiesmode",
   "shapingpenalty",
   "snapshotpar",
+  "srule",
   "supmarkmode",
   "swapcsvalues",
   "tabsize",
@@ -628,9 +637,11 @@ return {
   "uleaders",
   "undent",
   "unexpandedloop",
+  "unhpack",
   "unletfrozen",
   "unletprotected",
   "untraced",
+  "unvpack",
   "vpack",
   "wordboundary",
   "wrapuppar",
@@ -772,7 +783,6 @@ return {
   "advance",
   "afterassignment",
   "aftergroup",
-  "aligncontent",
   "atop",
   "atopwithdelims",
   "badness",
@@ -850,12 +860,10 @@ return {
   "font",
   "fontdimen",
   "fontname",
-  "fontspecifiedname",
   "futurelet",
   "gdef",
   "global",
   "globaldefs",
-  "glyph",
   "halign",
   "hangafter",
   "hangindent",
@@ -866,7 +874,6 @@ return {
   "hfilneg",
   "hfuzz",
   "holdinginserts",
-  "holdingmigrations",
   "hrule",
   "hsize",
   "hskip",
@@ -937,9 +944,6 @@ return {
   "maxdeadcycles",
   "maxdepth",
   "meaning",
-  "meaningasis",
-  "meaningfull",
-  "meaningless",
   "medmuskip",
   "message",
   "middle",
@@ -969,7 +973,6 @@ return {
   "over",
   "overfullrule",
   "overline",
-  "overshoot",
   "overwithdelims",
   "pagedepth",
   "pagefilllstretch",
@@ -1004,7 +1007,6 @@ return {
   "righthyphenmin",
   "rightskip",
   "romannumeral",
-  "scaledfontdimen",
   "scriptfont",
   "scriptscriptfont",
   "scriptscriptstyle",
@@ -1032,7 +1034,6 @@ return {
   "splitfirstmark",
   "splitmaxdepth",
   "splittopskip",
-  "srule",
   "string",
   "tabskip",
   "textfont",
@@ -1061,13 +1062,11 @@ return {
   "underline",
   "unhbox",
   "unhcopy",
-  "unhpack",
   "unkern",
   "unpenalty",
   "unskip",
   "unvbox",
   "unvcopy",
-  "unvpack",
   "uppercase",
   "vadjust",
   "valign",
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index dc2b82185..3e3adfbe6 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 b92cffbec..28adce871 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/mkiv/util-tab.lua b/tex/context/base/mkiv/util-tab.lua
index 7f372b6b5..64fa1af4f 100644
--- a/tex/context/base/mkiv/util-tab.lua
+++ b/tex/context/base/mkiv/util-tab.lua
@@ -996,3 +996,25 @@ function combine(target,source)
 end
 
 table.combine = combine
+
+-- If needed we can add something (some discussion on the list but I'm not sure if
+-- it makes sense because merging such mixed tables is quite unusual.
+--
+-- function table.himerged(...)
+--     local result = { }
+--     local r      = 0
+--     for i=1,select("#",...) do
+--         local s = select(i,...)
+--         if s then
+--             for k, v in next, s do
+--                 if type(k) == "number"  then
+--                     r = r + 1
+--                     result[r] = v
+--                 else
+--                     result[k] = v
+--                 end
+--             end
+--         end
+--     end
+--     return result
+-- end
diff --git a/tex/context/base/mkxl/catc-ini.mkxl b/tex/context/base/mkxl/catc-ini.mkxl
index 5b33db981..4376acd83 100644
--- a/tex/context/base/mkxl/catc-ini.mkxl
+++ b/tex/context/base/mkxl/catc-ini.mkxl
@@ -165,17 +165,29 @@
 %D This can be used when a direct definition has been done and the selector has been
 %D lost. A problem is that \type {\next} needs to be unique (as it gets bound) (still?).
 
+% \def\syst_catcodes_reinstate_normal
+%   {\begingroup
+%    \edef\temp{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}%
+%    \global\letcharcode\c_syst_catcodes_b\temp
+%    \endgroup}
+%
+% \def\syst_catcodes_reinstate_unexpanded
+%   {\begingroup
+%    \protected\edef\temp{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}%
+%    \global\letcharcode\c_syst_catcodes_b\temp
+%    \endgroup}
+
+% I really need to get rid of this ...
+
+\let\m_syst_catcodes_temp\relax
+
 \def\syst_catcodes_reinstate_normal
-  {\begingroup
-   \edef\temp{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}%
-   \global\letcharcode\c_syst_catcodes_b\temp
-   \endgroup}
+  {\edef\m_syst_catcodes_temp{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}%
+   \letcharcode\c_syst_catcodes_b\m_syst_catcodes_temp}
 
 \def\syst_catcodes_reinstate_unexpanded
-  {\begingroup
-   \protected\edef\temp{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}%
-   \global\letcharcode\c_syst_catcodes_b\temp
-   \endgroup}
+  {\protected\edef\m_syst_catcodes_temp{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}%
+   \letcharcode\c_syst_catcodes_b\m_syst_catcodes_temp}
 
 \newconstant\defaultcatcodetable
 
diff --git a/tex/context/base/mkxl/char-prv.lmt b/tex/context/base/mkxl/char-prv.lmt
index bb0377a75..07a72d53e 100644
--- a/tex/context/base/mkxl/char-prv.lmt
+++ b/tex/context/base/mkxl/char-prv.lmt
@@ -208,40 +208,6 @@ characters.private={
    unicodeslot=0xFE937,
   },
   --
-  [0xFE942]={
-   description="COMBINING REVERSE ANNUITY SYMBOL BASE",
-   unicodeslot=0xFE942,
-  },
-  [0xFE943]={
-   description="COMBINING REVERSE ANNUITY SYMBOL FILL",
-   unicodeslot=0xFE942,
-  },
-  --
-  [0xFE944]={
-   description="COMBINING FOURIER CIRCUMFLEX BASE",
-   unicodeslot=0xFE942,
-  },
-  [0xFE945]={
-   description="COMBINING FOURIER CIRCUMFLEX FILL",
-   unicodeslot=0xFE942,
-  },
-  [0xFE946]={
-   description="COMBINING FOURIER TILDE BASE",
-   unicodeslot=0xFE942,
-  },
-  [0xFE947]={
-   description="COMBINING FOURIER TILDE FILL",
-   unicodeslot=0xFE942,
-  },
-  [0xFE948]={
-   description="COMBINING FOURIER CARON BASE",
-   unicodeslot=0xFE942,
-  },
-  [0xFE949]={
-   description="COMBINING FOURIER CARON FILL",
-   unicodeslot=0xFE942,
-  },
-  --
   [0xFE957]={ -- vfu
    description="SMASHED PRIME 0x02057",
    unicodeslot=0xFE957,
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 44470eaf7..a9631b7bb 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{2022.08.25 19:18}
+\newcontextversion{2022.09.10 02:42}
 
 %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 8baf5a786..4ec59e791 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{2022.08.25 19:18}
+\immutable\edef\contextversion{2022.09.10 02:42}
 
 %overloadmode 1 % check frozen / warning
 %overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/core-con.mkxl b/tex/context/base/mkxl/core-con.mkxl
index 645eb2308..9e2b05778 100644
--- a/tex/context/base/mkxl/core-con.mkxl
+++ b/tex/context/base/mkxl/core-con.mkxl
@@ -552,7 +552,7 @@
 \installcorenamespace {conversionwords}
 
 %D It might be better to move more to \LUA\ as we also need conversion there and
-%D doublicating logic doesn't make things cleaner. It means that all conversions
+%D duplicating logic doesn't make things cleaner. It means that all conversions
 %D will get a language argument too. However, we permit definitions at the \TEX\ end
 %D so we have to provide some hybrid method.
 
diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt
index 9a72d834d..69adc09a9 100644
--- a/tex/context/base/mkxl/driv-shp.lmt
+++ b/tex/context/base/mkxl/driv-shp.lmt
@@ -990,6 +990,8 @@ local gluewidth = effectiveglue(current,this_box,true)
                     local usedorientation = false
                     if hasanchor then
                         anchor, source, target = getanchors(current)
+-- print(getanchors(current))
+-- if not anchor then anchor = 0 end
                     end
                     if hasorientation then
                         local orientation, xoffset, yoffset, woffset, hoffset, doffset = getorientation(current)
diff --git a/tex/context/base/mkxl/font-ots.lmt b/tex/context/base/mkxl/font-ots.lmt
index 3b7e6dbc3..2ab52a35a 100644
--- a/tex/context/base/mkxl/font-ots.lmt
+++ b/tex/context/base/mkxl/font-ots.lmt
@@ -435,7 +435,7 @@ end
 -- However, for arabic we need to keep them around for the sake of mark placement
 -- and indices.
 
-local function flattendisk(head,disc)
+local function flattendisk(head,disc) -- happen seldom, otherwise can be a helper
     local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
     local prev, next = getboth(disc)
     local ishead = head == disc
@@ -472,7 +472,7 @@ local function flattendisk(head,disc)
     end
 end
 
-local function appenddisc(disc,list)
+local function appenddisc(disc,list) -- happen seldom, otherwise can be a helper
     local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
     local posthead    = list
     local replacehead = copynodelist(list)
@@ -3955,19 +3955,11 @@ do
                     local lookupcache = step.coverage
                     while start do
                         local nxt, char, id = isnextchar(start,font,dynamic,state) -- we can move the data/state checks here
--- if forcetestrun and sequence.name == "s_s_7" then
---     if nuts.getid(start) == nodecodes.glyph then
---         print("C F D S",start,char,font,dynamic,state,nuts,getstate(start))
---     end
--- end
                         if char then
                             if skiphash and skiphash[char] then -- we never needed it here but let's try
                                 start = nxt
                             else
                                 local lookupmatch = lookupcache[char]
--- if forcetestrun and sequence.name == "s_s_7" then
---     print(lookupmatch)
--- end
                                 if lookupmatch then
                                     currentscale, currentxscale, currentyscale = getscales(start)
                                     local ok, df
diff --git a/tex/context/base/mkxl/lang-mis.mkxl b/tex/context/base/mkxl/lang-mis.mkxl
index 5aa40537c..48c2fa1cd 100644
--- a/tex/context/base/mkxl/lang-mis.mkxl
+++ b/tex/context/base/mkxl/lang-mis.mkxl
@@ -220,7 +220,7 @@
      \fi
    \endcsname}
 
-\setvalue{\??discretionarymode n}#1%
+\defcsname\??discretionarymode n\endcsname#1%
   {\detokenize{#1}}
 
 %D The macro \type{\lang_discretionaries_check_before} takes care of loners like
@@ -257,9 +257,9 @@
    \ifx          :\nexttoken \settrue \punctafterdiscretionary \orelse
    \ifx          ;\nexttoken \settrue \punctafterdiscretionary \fi}
 
-\letvalue{\??discretionarymode m}\handlemathmodediscretionary
+\letcsname\??discretionarymode m\endcsname\handlemathmodediscretionary
 
-\setvalue{\??discretionarymode t}#1%
+\defcsname\??discretionarymode t\endcsname#1%
   {\bgroup
    \let\nextnextnext\egroup
    \def\next##1#1%
@@ -349,7 +349,7 @@
      \fi
    \endcsname}
 
-\setuvalue{\??discretionarymode d}#1%
+\protected\defcsname\??discretionarymode d\endcsname#1%
   {\edef\lang_discretionaries_token{\detokenize{#1}}%
    \let\lang_discretionaries_action\compoundhyphen
    \ifcsname\??discretionaryaction\lang_discretionaries_token\endcsname
@@ -358,7 +358,7 @@
      \expandafter\indirectdiscretionary
    \fi{#1}}
 
-\setuvalue{\??discretionarymode i}#1%
+\protected\defcsname\??discretionarymode i\endcsname#1%
  %{\prewordbreak\discretionary{\hbox{#1}}{}{\hbox{#1}}\postwordbreak}
   {\wordboundary\discretionary{\hbox{#1}}{}{\hbox{#1}}\wordboundary}
  %{\discretionary options \plusthree{\hbox{#1}}{}{\hbox{#1}}}
diff --git a/tex/context/base/mkxl/lpdf-lmt.lmt b/tex/context/base/mkxl/lpdf-lmt.lmt
index 76867974a..bf1142119 100644
--- a/tex/context/base/mkxl/lpdf-lmt.lmt
+++ b/tex/context/base/mkxl/lpdf-lmt.lmt
@@ -2905,6 +2905,8 @@ local openfile, closefile  do
     local close    = false
     local update   = false
 
+    directives.enable("backend.pdf.inmemory", function(v) inmemory = true end)
+
  -- local banner <const> = "%\xCC\xD5\xC1\xD4\xC5\xD8\xD0\xC4\xC6\010"     -- LUATEXPDF  (+128)
     local banner <const> = "%\xC3\xCF\xCE\xD4\xC5\xD8\xD4\xD0\xC4\xC6\010" -- CONTEXTPDF (+128)
 
diff --git a/tex/context/base/mkxl/luat-log.lmt b/tex/context/base/mkxl/luat-log.lmt
index dd6c1b990..0c2405b75 100644
--- a/tex/context/base/mkxl/luat-log.lmt
+++ b/tex/context/base/mkxl/luat-log.lmt
@@ -630,29 +630,35 @@ end
 -- logs.errors=characters
 -- logs.errors=missing
 -- logs.errors=*
+-- logs.quitonerror=missing modules
 
 do
 
     local finalactions  = { }
     local fatalerrors   = { }
     local possiblefatal = { }
+    local quitonerror   = { }
     local loggingerrors = false
 
     function logs.loggingerrors()
         return loggingerrors
     end
 
-    directives.register("logs.errors",function(v)
+    local function register(v)
         loggingerrors = v
         if type(v) == "string" then
-            fatalerrors = settings_to_hash(v)
-            for k, v in next, fatalerrors do
-                fatalerrors[k] = string.topattern(k)
+            local target = settings_to_hash(v)
+            for k, v in next, target do
+                target[k] = string.topattern(k)
             end
+            return target
         else
-            fatalerrors = { }
+            return { }
         end
-    end)
+    end
+
+    directives.register("logs.errors",     function(v) fatalerrors = register(v) end)
+    directives.register("logs.quitonerror",function(v) quitonerror = register(v) end)
 
     function logs.registerfinalactions(...)
         insert(finalactions,...) -- so we can force an order if needed
@@ -662,6 +668,7 @@ do
     local report = nil
     local state  = nil
     local target = nil
+    local fatal  = false
 
     local function startlogging(t,r,w,s)
         target = t
@@ -692,6 +699,10 @@ do
         end
         poptarget()
         state = oldstate
+        if fatal then
+            logs.report("error logging","error marked as fatal")
+            luatex.abort()
+        end
     end
 
     function logs.startfilelogging(...)
@@ -713,6 +724,11 @@ do
         if fatalerrors[w] then
             possiblefatal[w] = true
         else
+            for k, v in next, quitonerror do
+                if find(w,v) then
+                    fatal = true
+                end
+            end
             for k, v in next, fatalerrors do
                 if find(w,v) then
                     possiblefatal[w] = true
diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt
index 14c0a94ce..4f12bf92e 100644
--- a/tex/context/base/mkxl/math-act.lmt
+++ b/tex/context/base/mkxl/math-act.lmt
@@ -1746,12 +1746,21 @@ do
                 local method   = entry[2]
                 local fraction = entry[3]
                 local width    = 0
-                if how == "c" then
-                    width = characters[fraction].width  -- char
-                elseif how == "s" then
-                    width = fraction * parameters.space -- space
+                local height   = 0
+             -- local depth    = 0
+                if method == "c" then
+                    local template = characters[fraction]
+                    width  = template.width
+                    height = template.height
+                 -- depth  = template.depth
+                elseif method == "s" then
+                    width  = fraction * parameters.space -- space
+                    height = 0
+                 -- depth  = 0
                 else
                     width = fraction * parameters.quad  -- quad
+                    height = 0
+                 -- depth  = 0
                 end
                 if trace_tweaking then
                     report_tweak("setting width of %U to %p",target,original,unicode,width)
@@ -1759,6 +1768,8 @@ do
                 characters[unicode] = {
                     width    = width,
                  -- advance  = width,
+                    height   = height,
+                 -- depth    = depth,
                     unicode  = unicode,
                     commands = {
                      -- { "slot", 0, 32 },
@@ -1990,10 +2001,12 @@ do
     -- radicals and actuarians are never seen together. We could also have a smaller
     -- extender.
 
+    local nps = fonts.helpers.newprivateslot
+
     local radical   <const> = 0x0221A
-    local actuarian <const> = 0x020E7
-    local nairautca <const> = 0xFE942
-    local placehold <const> = 0xFE943
+    local actuarian <const> = nps("delimited right annuity") -- 0x020E7
+    local nairautca <const> = nps("delimited left annuity" )
+    local placehold <const> = nps("delimited ghost annuity")
 
     function mathtweaks.addactuarian(target,original,parameters)
         local characters = target.characters
@@ -2004,6 +2017,21 @@ do
         local basedepth  = basechar.depth
         local basetotal  = baseheight + basedepth
         local used       = baseheight
+        --
+        characters[0x020E7] = {
+            width    = 6*linewidth,
+            height   = baseheight,
+            depth    = basedepth,
+            unicode  = actuarian,
+            callback = "devirtualize",
+            commands = {
+                upcommand[baseheight-4*linewidth],
+                { "rule", linewidth, 4*linewidth },
+                downcommand[basetotal/2-linewidth],
+                { "rule", basetotal/2, linewidth },
+            },
+        }
+        --
         characters[actuarian] = {
             width    = 2*linewidth,
             height   = baseheight,
@@ -2086,12 +2114,12 @@ do
     -- todo: make callback because we can delay it but then we need to stack
     -- callbacks
 
-    -- todo: use named privates for snippets
+    local nps = fonts.helpers.newprivateslot
 
     local list = {
-        { 0x302, 0xFE944, 0xFE945 },
-        { 0x303, 0xFE946, 0xFE947 },
-        { 0x30C, 0xFE948, 0xFE949 },
+        { 0x302, nps("delimited right hat"  ), nps("delimited ghost hat"  ) },
+        { 0x303, nps("delimited right tilde"), nps("delimited ghost tilde") },
+        { 0x30C, nps("delimited right check"), nps("delimited ghost check") },
     }
 
     function mathtweaks.addfourier(target,original,parameters)
diff --git a/tex/context/base/mkxl/math-ali.lmt b/tex/context/base/mkxl/math-ali.lmt
index 718975a50..87ea67c72 100644
--- a/tex/context/base/mkxl/math-ali.lmt
+++ b/tex/context/base/mkxl/math-ali.lmt
@@ -8,94 +8,285 @@ if not modules then modules = { } end modules ['math-ali'] = {
 
 local unpack = unpack
 local gsub = string.gsub
-local lpegmatch = lpeg.match
+local sort, keys = table.sort, table.keys
 local settings_to_array = utilities.parsers.settings_to_array
-
-local rows = utilities.parsers.groupedsplitat(";")
-local cols = utilities.parsers.groupedsplitat(",")
+local P, R, S, C, Cc, Ct, Cs = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cs
+local lpegmatch = lpeg.match
 
 local context = context
 
-local actions = {
-    transpose = function(m)
-        local t = { }
-        for j=1,#m[1] do
-            local r = { }
-            for i=1,#m do
-                r[i] = m[i][j]
-            end
-            t[j] = r
-        end
-        return t
-    end,
-    negate = function(m)
-        for i=1,#m do
-            local mi = m[i]
-            for j=1,#mi do
-                mi[j] = - mi[j]
+do
+
+    local rows = utilities.parsers.groupedsplitat(";")
+    local cols = utilities.parsers.groupedsplitat(",")
+
+    local actions = {
+        transpose = function(m)
+            local t = { }
+            for j=1,#m[1] do
+                local r = { }
+                for i=1,#m do
+                    r[i] = m[i][j]
+                end
+                t[j] = r
             end
-        end
-        return m
-    end,
-    scale = function(m,s)
-        s = tonumber(s)
-        if s then
+            return t
+        end,
+        negate = function(m)
             for i=1,#m do
                 local mi = m[i]
                 for j=1,#mi do
-                    mi[j] = s*mi[j]
+                    mi[j] = - mi[j]
                 end
             end
-        end
-        return m
-    end,
-}
+            return m
+        end,
+        scale = function(m,s)
+            s = tonumber(s)
+            if s then
+                for i=1,#m do
+                    local mi = m[i]
+                    for j=1,#mi do
+                        mi[j] = s*mi[j]
+                    end
+                end
+            end
+            return m
+        end,
+    }
 
-local useractions = {
-}
+    local useractions = {
+    }
 
-interfaces.implement {
-    name      = "simplematrix",
-    arguments = "2 strings",
-    actions   = function(method,data)
-        local m = lpegmatch(rows,(gsub(data,"%s+"," ")))
-        for i=1,#m do
-            m[i] = lpegmatch(cols,m[i])
-        end
-        local methods = settings_to_array(method)
-        for i=1,#methods do
-            local detail = settings_to_array(methods[i])
-            local method = detail[1]
-            local action = actions[method] or useractions[method]
-            if action then
-                m = action(m,unpack(detail,2)) or m
+    interfaces.implement {
+        name      = "simplematrix",
+        arguments = "2 strings",
+        actions   = function(method,data)
+            local m = lpegmatch(rows,(gsub(data,"%s+"," ")))
+            for i=1,#m do
+                m[i] = lpegmatch(cols,m[i])
+            end
+            local methods = settings_to_array(method)
+            for i=1,#methods do
+                local detail = settings_to_array(methods[i])
+                local method = detail[1]
+                local action = actions[method] or useractions[method]
+                if action then
+                    m = action(m,unpack(detail,2)) or m
+                end
+            end
+            for i=1,#m do
+                context("\\NC %{ \\NC }t \\NR",m[i])
             end
         end
-        for i=1,#m do
-            context("\\NC %{ \\NC }t \\NR",m[i])
+    }
+
+    function mathematics.registersimplematrix(name,action)
+        if type(action) == "function" then
+            useractions[name] = action
         end
     end
-}
 
-function mathematics.registersimplematrix(name,action)
-    if type(action) == "function" then
-        useractions[name] = action
-    end
+    -- \cases{1, x>0 ; -1, x<0 }
+
+    interfaces.implement {
+        name      = "simplecases",
+        arguments = "2 strings",
+        actions   = function(method,data)
+            -- no methods yet
+            local m = lpegmatch(rows,(gsub(data,"%s+"," ")))
+            for i=1,#m do
+                m[i] = lpegmatch(cols,m[i])
+            end
+            for i=1,#m do
+                context("\\NC %{ \\NC }t \\NR",m[i])
+            end
+        end
+    }
+
 end
 
--- \cases{1, x>0 ; -1, x<0 }
+do
+
+    local relations = {
+        ["<"]   = "<", [">"]   = ">",
+        ["!<"]  = "≮", ["!>"]  = "≯",
+        ["<<"]  = "≪", [">>"] = "≫",
+        ["="]   = "=", ["=="]  = "=",
+        ["<>"]  = "≠", ["!="]  = "≠",
+        ["<="]  = "≤", [">="]  = "≥",
+        ["=<"]  = "≦", ["=>"]  = "≧",
+        ["!=<"] = "≰", ["!=>"] = "≱",
+        ["~"]   = "≈", ["~~"]  = "≈",
+    }
+
+    for k, v in next, table.copy(relations) do relations[v] = v end
+
+ -- local binaries = {
+ --     ["+"] = "+",
+ --     ["-"] = "-",
+ --     ["/"] = "/",
+ --     ["*"] = "",
+ -- }
+
+    local separators = {
+        [","] = true,
+        [";"] = true,
+    }
+
+    local alternatives = {
+        -- not that many
+    }
+
+    local p_sign     = S("-+")
+    local p_script   = S("^")^1
+    local p_number   = R("09","..")^1 + lpeg.patterns.nestedbraces
+    local p_alpha    = R("az","AZ")^1
+    local p_variable = p_alpha * (P("_") * (p_number + p_alpha))^-1
+
+    local spacing    = P(" ")^0
+    local script     = Cs(p_script * Cc("{") * p_sign^0 * (p_number + p_variable) * Cc("}"))
+    local sign       = C(p_sign) + Cc("+")
+    local number     = C(p_number)
+    local variable   = C(p_variable)
+ -- local binary     = lpeg.utfchartabletopattern(binaries) / binaries
+    local relation   = lpeg.utfchartabletopattern(relations) / relations
+    local separator  = lpeg.utfchartabletopattern(separators)
+
+    local snippet = Ct (
+        (
+              spacing * sign * spacing * number    * spacing * variable
+            + spacing * sign * spacing * number    * spacing * Cc(false)
+            + spacing * sign * spacing * Cc(false) * spacing * variable
+        ) * (script + Cc(false))
+    )
+
+    local parser = Ct ( Ct (
+        ( Ct ( snippet^1 ) * spacing * relation    )^1
+      * ( Ct ( snippet^1 ) * spacing * separator^0 )
+    )^1 )
+
+    local num = "!"
+
+    local ctx_NC, ctx_NR = context.NC, context.NR
+    local ctx_typ = context.typ
+    local ctx_ord, ctx_rel = context.mathord, context.mathrel
+
+    local clean = table.setmetatableindex(function(t,k)
+        local v = gsub(k,"[{}]","")
+        t[k] = v
+        return v
+    end)
 
-interfaces.implement {
-    name      = "simplecases",
-    arguments = "2 strings",
-    actions   = function(method,data)
-        -- no methods yet
-        local m = lpegmatch(rows,(gsub(data,"%s+"," ")))
-        for i=1,#m do
-            m[i] = lpegmatch(cols,m[i])
+    alternatives.equationsystem = function(action,str)
+        local rows = lpegmatch(parser,str)
+        if not rows then
+            ctx_typ("bad system, case 1: %s",1,str)
+            return
         end
-        for i=1,#m do
-            context("\\NC %{ \\NC }t \\NR",m[i])
+        local nrow = #rows
+        local all = table.setmetatableindex("table")
+        for r=1,nrow do
+            local row = rows[r]
+            for s=1,#row,2 do
+                local set = row[s]
+                for v=1,#set do
+                    local vvv = set[v]
+                    local var = vvv[3]
+                    if not var then
+                        var = num
+                    end
+                    if set[var] then
+                        print("bad system, two constants")
+                    end
+                    set[var] = set[v]
+                    all[s][var] = true
+                    set[v] = nil
+                end
+            end
+        end
+        --
+        local cnt = #rows[1]
+        for r=1,nrow do
+            if #rows[r] ~= cnt then
+                ctx_typ("bad system, case %i: %s",2,str)
+                return
+            end
+        end
+        for r=1,#rows[1] do
+            local a = keys(all[r])
+            sort(a,function(a,b)
+                return clean[a] < clean[b]
+            end)
+            all[r] = a
+        end
+        --
+        for r=1,nrow do
+            local row = rows[r]
+            for r=1,#row do
+                local set = row[r]
+                local how = all[r]
+                if #how > 0 then
+                 -- local done = false
+                    for i=1,#how do
+                        local k = how[i]
+                        local e = set[k]
+                        if e then
+                            ctx_NC()
+                         -- if not done and e[1] == "+" then
+                            if i == 1 and e[1] == "+" then
+                             -- ctx_ord("")
+                             -- ctx_hphantom(e[1])
+                             -- ctx_ord("")
+                            else
+                                ctx_ord("")
+                                context(e[1])
+                                ctx_ord("")
+                             -- done = true
+                            end
+                            ctx_NC()
+                            if e[2] then
+                                context(e[2])
+                             -- done = true
+                            end
+                            if e[3] then
+                                context(e[3])
+                             -- done = true
+                            end
+                            if e[4] then
+                                context(e[4])
+                             -- done = true
+                            end
+                        else
+                            ctx_NC()
+                         -- ctx_mathord("")
+                            ctx_NC()
+                        end
+                    end
+                else
+                    ctx_NC()
+                    ctx_ord("")
+                    context(set)
+                    ctx_ord("")
+                end
+            end
+            ctx_NR()
         end
     end
-}
+
+    interfaces.implement {
+        name      = "simplealign",
+     -- public    = true,
+        protected = true,
+        arguments = "3 strings",
+        actions   = function(alternative,action,str)
+            local a = alternatives[alternative]
+            if a then
+                a(action,str)
+            else
+                context(str)
+            end
+        end
+    }
+
+end
diff --git a/tex/context/base/mkxl/math-ali.mkxl b/tex/context/base/mkxl/math-ali.mkxl
index aaf76c9b1..b6b037117 100644
--- a/tex/context/base/mkxl/math-ali.mkxl
+++ b/tex/context/base/mkxl/math-ali.mkxl
@@ -2760,6 +2760,61 @@
     \expandafter\startsubstack\the\scratchtoks\strut\stopsubstack
     \endgroup}
 
+%D Similar to simplecases:
+%D
+%D \starttyping
+%D \startformula
+%D     \equationsystem {
+%D        {(1-a)}x^{2x} - 3y_2 + 14z  = 2 + x,
+%D        {(1-a)}x^2    - 3y_2 +  4z <= 62,
+%D        {(1-a)}x^a    - 3y_2 +  4z >= 12,
+%D        {(1-a)}x^{2a} - 3y_2 + 24z != 4,
+%D               x^^2   - 3y_2 +  4z ~  1,
+%D               x^^2   - 3y_2 +  4z ≠  1,
+%D             -2x      -         4z <> 10,
+%D     }
+%D \stopformula
+%D \stoptyping
+
+\permanent\tolerant\protected\def\math_align_simple[#1]#*[#2]#:#3%
+  {\begingroup
+   \edef\currentmathsimplealign{#1}%
+   \setupcurrentmathsimplealign[#2]%
+   \math_simplealign_start[\currentmathsimplealign]%
+   \clf_simplealign{\mathsimplealignparameter\c!alternative}{\mathsimplealignparameter\c!action}{#3}%
+   \math_simplealign_stop
+   \endgroup}
+
+\appendtoks
+    \edef\p_simplecommand{\mathsimplealignparameter\c!simplecommand}%
+    \ifempty\p_simplecommand\else
+        \frozen\protected\instance\edefcsname\p_simplecommand\endcsname{\math_align_simple[\currentmathsimplealign]}%
+    \fi
+\to \everydefinemathsimplealign
+
+\definemathsimplealign % new !
+  [equationsystem]
+  [\c!simplecommand=equationsystem,
+   \c!alternative=equationsystem, % for the moment we use this key
+   \c!align={all:right},
+   \c!distance=\v!math,
+   \c!left=,
+   \c!right=]
+
+\definemathsimplealign
+  [lequationsystem]
+  [equationsystem]
+  [\c!simplecommand=lequationsystem,
+   \c!left={\startmathfenced[cases]},
+   \c!right=\stopmathfenced]
+
+\definemathsimplealign
+  [requationsystem]
+  [equationsystem]
+  [\c!simplecommand=requationsystem,
+   \c!left={\startmathfenced[sesac]},
+   \c!right=\stopmathfenced]
+
 \protect \endinput
 
 % \placeformula \startformula[-] \startmatrix
diff --git a/tex/context/base/mkxl/math-def.mkxl b/tex/context/base/mkxl/math-def.mkxl
index d46506add..16c65cf55 100644
--- a/tex/context/base/mkxl/math-def.mkxl
+++ b/tex/context/base/mkxl/math-def.mkxl
@@ -49,9 +49,9 @@
 \definemathfunction [exp]
 \definemathfunction [gcd]     [\c!mathlimits=\v!yes]
 \definemathfunction [hom]
-\definemathfunction [inf]     [\c!mathlimits=\v!yes]
-\definemathfunction [inv]     [\c!mathlimits=\v!yes]
-\definemathfunction [injlim]  [\c!mathlimits=\v!yes]
+\definemathfunction [inf]     [\c!mathlimits=\v!auto]
+\definemathfunction [inv]     [\c!mathlimits=\v!auto]
+\definemathfunction [injlim]  [\c!mathlimits=\v!auto]
 \definemathfunction [ker]
 \definemathfunction [lg]
 \definemathfunction [liminf]  [\c!mathlimits=\v!auto]
@@ -64,12 +64,12 @@
 \definemathfunction [min]     [\c!mathlimits=\v!auto]
 \definemathfunction [mod]     [\c!mathlimits=\v!yes]
 %definemathfunction [div]     [\c!mathlimits=\v!yes]
-\definemathfunction [projlim] [\c!mathlimits=\v!yes]
+\definemathfunction [projlim] [\c!mathlimits=\v!auto]
 \definemathfunction [Pr]      [\c!mathlimits=\v!yes]
 \definemathfunction [sec]
 \definemathfunction [sinh]
 \definemathfunction [sin]
-\definemathfunction [sup]     [\c!mathlimits=\v!yes]
+\definemathfunction [sup]     [\c!mathlimits=\v!auto]
 \definemathfunction [tanh]
 \definemathfunction [tan]
 \definemathfunction [diff]
diff --git a/tex/context/base/mkxl/math-del.mklx b/tex/context/base/mkxl/math-del.mklx
index d046a0912..edfd77de2 100644
--- a/tex/context/base/mkxl/math-del.mklx
+++ b/tex/context/base/mkxl/math-del.mklx
@@ -84,17 +84,27 @@
      {\popcolor#body}%
    \fi}
 
-% todo:
-%
-% \setupmathdelimited
-%   [topoffset=.2\exheight]
-%
-% \definemathdelimited
-%   [fourier]
-%   [rule=no,
-%    left=\zerocount,
-%    right="FE944] % 46 48
-%
+\integerdef\delimitedrighthatuc   \privatecharactercode{delimited right hat}
+\integerdef\delimitedrighttildeuc \privatecharactercode{delimited right tilde}
+\integerdef\delimitedrightcheckuc \privatecharactercode{delimited right check}
+
+% todo: some more .. are the offsets okay?
+
+\definemathdelimited
+  [fourier]
+  [\c!topoffset=.2\exheight,
+   \c!right=\delimitedrighthatuc]
+
+\definemathdelimited
+  [inversefourier]
+  [fourier]
+  [\c!right=\delimitedrightcheckuc]
+
+\definemathdelimited
+  [fuzzyfourier]
+  [fourier]
+  [\c!right=\delimitedrighttildeuc]
+
 % $ \autofences \fourier{(z+\frac12)} + \courier{(z+\frac12)} + \xourier{(z+\frac12)} $
 
 \protect \endinput
diff --git a/tex/context/base/mkxl/math-fen.mkxl b/tex/context/base/mkxl/math-fen.mkxl
index aeed32fcf..5dd7ee118 100644
--- a/tex/context/base/mkxl/math-fen.mkxl
+++ b/tex/context/base/mkxl/math-fen.mkxl
@@ -270,11 +270,32 @@
 \aliased\let\fence \relax
 \aliased\let\fenced\relax
 
+\protected\def\math_fenced_middle_bar  {\mfence |\relax}
+\protected\def\math_fenced_middle_colon{\mfence :\relax}
+\protected\def\math_fenced_middle_comma{\mathatom \s!leftclass \mathpunctuationcode \s!rightclass \mathmiddlecode {,}}
+
+\startsetups math:fence:set:bar
+    \aliased\let\suchthat\math_fenced_middle_bar
+    \aliased\let\where   \math_fenced_middle_comma
+    \aliased\let\and     \math_fenced_middle_comma
+\stopsetups
+
+\startsetups math:fence:set:colon
+    \aliased\let\suchthat\math_fenced_middle_colon
+    \aliased\let\where   \math_fenced_middle_comma
+    \aliased\let\and     \math_fenced_middle_comma
+\stopsetups
+
+\startsetups math:fence:set
+    \directsetup{math:fence:set:bar}
+\stopsetups
+
 \protected\def\math_fenced_middle_common
   {\math_fenced_middle} % redefined inside atom
 
 \protected\def\math_fenced_fenced_common
   {\startusemathstyleparameter\mathfenceparameter\c!mathstyle
+   \usesetupsparameter\mathfenceparameter
    \enforced\let\fence\math_fenced_middle_common}
 
 \protected\def\math_fenced_fenced_start#1%
@@ -604,7 +625,7 @@
    \math_fenced_common\Uright\c!rightclass\math_fenced_x_p_right\c!rightsource
    \advance\c_math_fence_nesting\minusone}
 
-\def\math_fenced_x_middle_normal
+\def\math_fenced_x_middle
   {\math_fenced_common\Umiddle\c!middleclass\math_fenced_x_p_middle\c!middlesource}
 
 % the expandafter permits \left\Uchar...
diff --git a/tex/context/base/mkxl/math-ini.lmt b/tex/context/base/mkxl/math-ini.lmt
index 81ac23f43..81138b2e2 100644
--- a/tex/context/base/mkxl/math-ini.lmt
+++ b/tex/context/base/mkxl/math-ini.lmt
@@ -368,6 +368,7 @@ registerengineclass("textpunctuation", "tpu")
 registerengineclass("unspaced")
 registerengineclass("experimental")
 registerengineclass("fake")
+registerengineclass("numbergroup",     "ngr")
 
 registerengineclass("maybeordinary")
 registerengineclass("mayberelation")
diff --git a/tex/context/base/mkxl/math-ini.mkxl b/tex/context/base/mkxl/math-ini.mkxl
index 5b5610ff5..a1e5c29a6 100644
--- a/tex/context/base/mkxl/math-ini.mkxl
+++ b/tex/context/base/mkxl/math-ini.mkxl
@@ -176,6 +176,7 @@
 \setnewconstant\mathunspacedcode        \mathclassvalue unspaced        % for cases where we don't want spacing at all
 \setnewconstant\mathexperimentalcode    \mathclassvalue experimental    % for MS and HH testing purposed only
 \setnewconstant\mathunarycode           \mathclassvalue unary           % dedicated to Alan
+\setnewconstant\mathnumbergroupcode     \mathclassvalue numbergroup
 
 \setnewconstant\mathbegincode           \mathclassvalue begin
 \setnewconstant\mathendcode             \mathclassvalue end
@@ -231,6 +232,9 @@
 \copymathspacing \mathmayberelationcode  \mathrelationcode
 \copymathspacing \mathmaybebinarycode    \mathbinarycode
 
+%copymathspacing \mathnumbergroupcode  \mathpunctuationcode
+\copymathspacing \mathnumbergroupcode  \mathrelationcode     % for now
+
 \setnewconstant\mathlimopcode \plusone
 \setnewconstant\mathnolopcode \plusone
 
@@ -552,6 +556,7 @@
  % +\checkligatureclassoptioncode
    +\flattenclassoptioncode
    +\checkkernpairclassoptioncode
+   +\removeitaliccorrectionclassoptioncode
 \relax
 
 \setmathoptions\mathvariablecode\numexpr
@@ -730,6 +735,8 @@
 \definesystemattribute[mathcollapsing] [public]
 \definesystemattribute[mathunstack]    [public]
 \definesystemattribute[mathvariant]    [public]
+\definesystemattribute[mathnumbers]    [public]
+\definesystemattribute[mathspacing]    [public]
 
 \definesystemattribute[displaymath]    [public]
 
@@ -1206,29 +1213,29 @@
     \inherited\setmathspacing \mathclosecode       \mathfractioncode     \allscriptstyles \pettymuskip
   % \inherited\setmathspacing \mathclosecode       \mathradicalcode      \allmathstyles   \zeromuskip
     %
-    \inherited\setmathspacing \mathpunctuationcode \mathordinarycode     \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathordinarycode     \allscriptstyles \pettymuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathoperatorcode     \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathoperatorcode     \allscriptstyles \pettymuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathordinarycode     \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathordinarycode     \allscriptstyles \thinmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathoperatorcode     \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathoperatorcode     \allscriptstyles \thinmuskip
   % \inherited\setmathspacing \mathpunctuationcode \mathbinarycode       \allmathstyles   \zeromuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathrelationcode     \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathrelationcode     \allscriptstyles \pettymuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathopencode         \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathopencode         \allscriptstyles \pettymuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathrelationcode     \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathrelationcode     \allscriptstyles \thinmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathopencode         \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathopencode         \allscriptstyles \thinmuskip
     \inherited\setmathspacing \mathpunctuationcode \mathmiddlecode       \allsplitstyles  \thickmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathmiddlecode       \allscriptstyles \pettymuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathclosecode        \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathclosecode        \allscriptstyles \pettymuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathpunctuationcode  \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathpunctuationcode  \allscriptstyles \pettymuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathconstructcode    \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathconstructcode    \allscriptstyles \pettymuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathellipsiscode     \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathellipsiscode     \allscriptstyles \pettymuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathfractioncode     \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathfractioncode     \allscriptstyles \pettymuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathradicalcode      \allsplitstyles  \thinmuskip
-    \inherited\setmathspacing \mathpunctuationcode \mathradicalcode      \allscriptstyles \pettymuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathmiddlecode       \allscriptstyles \thinmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathclosecode        \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathclosecode        \allscriptstyles \thinmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathpunctuationcode  \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathpunctuationcode  \allscriptstyles \thinmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathconstructcode    \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathconstructcode    \allscriptstyles \thinmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathellipsiscode     \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathellipsiscode     \allscriptstyles \thinmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathfractioncode     \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathfractioncode     \allscriptstyles \thinmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathradicalcode      \allsplitstyles  \medmuskip
+    \inherited\setmathspacing \mathpunctuationcode \mathradicalcode      \allscriptstyles \thinmuskip
     %
     \inherited\setmathspacing \mathconstructcode   \mathordinarycode     \allsplitstyles  \thinmuskip
     \inherited\setmathspacing \mathconstructcode   \mathordinarycode     \allscriptstyles \pettymuskip
@@ -2452,16 +2459,39 @@
 %D we can stick to numbers. At some point this will change because we can now
 %D control in in the engine and goodies per font.
 
-\installcorenamespace{mathitalics}
+% \installcorenamespace{mathitalics}
+%
+% \setnewconstant\c_math_italics_attribute\attributeunsetvalue
+%
+% \letcsname\??mathitalics       1\endcsname\plusone              % fontitalics
+% \letcsname\??mathitalics       2\endcsname\plustwo              % fontdata
+% \letcsname\??mathitalics       3\endcsname\plusthree            % quad based
+% \letcsname\??mathitalics       4\endcsname\plusfour             % combination of 1 and 3
+% \letcsname\??mathitalics \v!none\endcsname\attributeunsetvalue
+% \letcsname\??mathitalics\v!reset\endcsname\attributeunsetvalue
+%
+% \def\math_italics_initialize
+%   {\ifnum\c_math_italics_attribute=\attributeunsetvalue \else
+%      \clf_initializemathitalics % one time
+%      \glet\math_italics_initialize\relax
+%    \fi}
+%
+% \appendtoks
+%     \edef\p_italics{\mathematicsparameter\s!italics}%
+%     \c_math_italics_attribute
+%         \ifcsname\??mathitalics\p_italics\endcsname\lastnamedcs\else\attributeunsetvalue\fi
+%     \relax
+%   % \math_italics_initialize
+% \to \everyswitchmathematics % only in mathematics
+%
+% \appendtoks
+%     \math_italics_initialize
+%     \c_attr_mathitalics\c_math_italics_attribute
+% \to \everymathematics
 
 \setnewconstant\c_math_italics_attribute\attributeunsetvalue
 
-\letcsname\??mathitalics       1\endcsname\plusone              % fontitalics
-\letcsname\??mathitalics       2\endcsname\plustwo              % fontdata
-\letcsname\??mathitalics       3\endcsname\plusthree            % quad based
-\letcsname\??mathitalics       4\endcsname\plusfour             % combination of 1 and 3
-\letcsname\??mathitalics \v!none\endcsname\attributeunsetvalue
-\letcsname\??mathitalics\v!reset\endcsname\attributeunsetvalue
+% merge these:
 
 \def\math_italics_initialize
   {\ifnum\c_math_italics_attribute=\attributeunsetvalue \else
@@ -2472,9 +2502,14 @@
 \appendtoks
     \edef\p_italics{\mathematicsparameter\s!italics}%
     \c_math_italics_attribute
-        \ifcsname\??mathitalics\p_italics\endcsname\lastnamedcs\else\attributeunsetvalue\fi
+      \ifx\p_italics\v!none
+        \attributeunsetvalue
+      \orelse\ifx\p_italics\v!reset
+        \attributeunsetvalue
+      \else
+        \plusone
+      \fi
     \relax
-  % \math_italics_initialize
 \to \everyswitchmathematics % only in mathematics
 
 \appendtoks
@@ -2482,9 +2517,6 @@
     \c_attr_mathitalics\c_math_italics_attribute
 \to \everymathematics
 
-% \setupmathematics % done later
-%   [\s!italics=3] % 4 is probably better
-
 % looks nicer but can generate bogus csnames
 %
 % \setvalue{\??mathitalics1}{\math_italics_initialize\c_math_italics_attribute\plusone  } % fontitalics
@@ -2539,11 +2571,11 @@
 % \protected\def\disablemathpunctuation{\setfalse\automathpunctuation}
 %
 % \appendtoks
-%     \doifelse{\mathematicsparameter\v!autopunctuation}\v!yes\settrue\setfalse\automathpunctuation
+%     \doifelse{\mathematicsparameter\c!autopunctuation}\v!yes\settrue\setfalse\automathpunctuation
 % \to \everyswitchmathematics
 %
 % \setupmathematics
-%   [\v!autopunctuation=\v!no]
+%   [\c!autopunctuation=\v!no]
 %
 % \def\math_punctuation_next{\ifx\nexttoken\blankspace\signalcharacter\fi}
 %
@@ -2609,12 +2641,12 @@
 
 % todo: use \Umathclass\c_math_comma\mathpunctcode etc for temporary switching
 
-\def\math_set_o_comma    {\Umathcode\c_math_comma    \mathordcode  \zerocount\c_math_comma}
-\def\math_set_p_comma    {\Umathcode\c_math_comma    \mathpunctcode\zerocount\c_math_comma}
-\def\math_set_o_period   {\Umathcode\c_math_period   \mathordcode  \zerocount\c_math_period}
-\def\math_set_p_period   {\Umathcode\c_math_period   \mathpunctcode\zerocount\c_math_period}
-\def\math_set_o_semicolon{\Umathcode\c_math_semicolon\mathordcode  \zerocount\c_math_semicolon}
-\def\math_set_p_semicolon{\Umathcode\c_math_semicolon\mathpunctcode\zerocount\c_math_semicolon}
+\def\math_set_o_comma    {\Umathcode\c_math_comma    \mathordinarycode   \zerocount\c_math_comma}
+\def\math_set_p_comma    {\Umathcode\c_math_comma    \mathpunctuationcode\zerocount\c_math_comma}
+\def\math_set_o_period   {\Umathcode\c_math_period   \mathordinarycode   \zerocount\c_math_period}
+\def\math_set_p_period   {\Umathcode\c_math_period   \mathpunctuationcode\zerocount\c_math_period}
+\def\math_set_o_semicolon{\Umathcode\c_math_semicolon\mathordinarycode   \zerocount\c_math_semicolon}
+\def\math_set_p_semicolon{\Umathcode\c_math_semicolon\mathpunctuationcode\zerocount\c_math_semicolon}
 
 \edef\math_set_o_both {\math_set_o_period\math_set_o_comma}
 \edef\math_set_p_both {\math_set_p_period\math_set_p_comma}
@@ -2633,9 +2665,9 @@
           \let\math_punctuation_yes_period   \math_punctuation_nop_period
           \let\math_punctuation_yes_semicolon\math_punctuation_all_semicolon
 
-\def\math_punctuation_comma_next    {\begingroup\Umathcode\c_math_comma    \ifx\nexttoken\blankspace\mathordcode\else\mathordcode\fi\zerocount\c_math_comma    ,\endgroup}
-\def\math_punctuation_period_next   {\begingroup\Umathcode\c_math_period   \ifx\nexttoken\blankspace\mathordcode\else\mathordcode\fi\zerocount\c_math_period   .\endgroup}
-\def\math_punctuation_semicolon_next{\begingroup\Umathcode\c_math_semicolon\ifx\nexttoken\blankspace\mathordcode\else\mathordcode\fi\zerocount\c_math_semicolon;\endgroup}
+\def\math_punctuation_comma_next    {\begingroup\Umathcode\c_math_comma    \ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\c_math_comma    ,\endgroup}
+\def\math_punctuation_period_next   {\begingroup\Umathcode\c_math_period   \ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\c_math_period   .\endgroup}
+\def\math_punctuation_semicolon_next{\begingroup\Umathcode\c_math_semicolon\ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\c_math_semicolon;\endgroup}
 
 \installcorenamespace {mathautopunctuation}
 
@@ -2704,12 +2736,12 @@
     \mathcode\c_math_comma    \c_math_special
     \mathcode\c_math_period   \c_math_special
     \mathcode\c_math_semicolon\c_math_special
-    \begincsname\??mathautopunctuation\mathematicsparameter\v!autopunctuation\endcsname
+    \begincsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname
 \to \everymathematics
 
 \appendtoks
-    \ifcsname\??mathautopunctuation\mathematicsparameter\v!autopunctuation\endcsname \else
-        \letmathematicsparameter\v!autopunctuation\v!no
+    \ifcsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname \else
+        \letmathematicsparameter\c!autopunctuation\v!no
     \fi
 \to \everysetupmathematics
 
@@ -2717,7 +2749,73 @@
 \permanent\protected\def\disablemathpunctuation{\csname\??mathautopunctuation\v!yes\endcsname}
 
 \setupmathematics
-  [\v!autopunctuation=\v!no] % no | yes | all | comma | yes,semicolon | all,semicolon
+  [\c!autopunctuation=\v!no] % no | yes | all | comma | yes,semicolon | all,semicolon
+
+%D The next replaces the above:
+
+% \startbuffer
+%     \im{x + 1,222,333.44 + x}\par
+%     \im{x + 1.222.333,44 + x}\par
+%     \im{x + 1, 222, 333. 44 + x}\par
+%     \im{(1.5, 1.5) + (1,5;1,5)}\par
+%     \im{111 2222}\par
+%     \im{f: \reals\to\reals}\par
+%     \im{f : \reals\to\reals}\par
+%     \im{f\colon\reals\to\reals}\par
+%     \im{f \colon\reals\to\reals}\par
+% \stopbuffer
+%
+% \startTEXpage[offset=1dk]
+%     \setupmathematics[autospacing=yes] \getbuffer \blank
+%     \setupmathematics[autonumbers=1]   \getbuffer \blank
+%     \setupmathematics[autonumbers=2]   \getbuffer \blank
+%     \setupmathematics[autonumbers=3]   \getbuffer \blank
+%     \setupmathematics[autonumbers=4]   \getbuffer \blank
+%     \setupmathematics[autonumbers=5]   \getbuffer \blank
+%     \setupmathematics[autonumbers=6]   \getbuffer \blank
+% \stopTEXpage
+
+\installcorenamespace{autospacing}
+
+\permanent\protected\def\enablemathautospacing
+  {\attribute\mathspacingattribute\plusone
+   \clf_initializemathspacing}
+
+\permanent\protected\def\disablemathautospacing
+  {\attribute\mathspacingattribute\attributeunsetvalue}
+
+\appendtoks
+    \ifcstok{\mathematicsparameter\c!autospacing}\v!yes
+      \enablemathautospacing
+    \else
+      \disablemathautospacing
+    \fi
+\to \everysetupmathematics
+
+\setupmathematics
+  [\c!autospacing=\v!no]
+
+\permanent\protected\def\enablemathautonumbers
+  {\attribute\mathnumbersattribute\plusone
+   \clf_initializemathnumbers}
+
+\permanent\protected\def\disablemathautonumbers
+  {\attribute\mathnumbersattribute\attributeunsetvalue}
+
+\appendtoks
+    \edef\p_autonumbers{\mathematicsparameter\c!autonumbers}%
+    \ifchknum\p_autonumbers\or
+      \enablemathautonumbers % default
+      \attribute\mathnumbersattribute\p_autonumbers\relax
+    \orelse\ifx\p_autonumbers\v!no
+      \disablemathautonumbers
+    \else
+      \enablemathautonumbers % default
+    \fi
+\to \everysetupmathematics
+
+\setupmathematics
+  [\c!autonumbers=\v!no]
 
 %D The consequences of setting this are as follows:
 %D
@@ -3418,54 +3516,143 @@
 %D
 %D \typebuffer \getbuffer
 
-\def\math_text_choice_font#1#2#%
-  {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
-   \hbox#2\bgroup
-   \bgroup
-   \aftergroup\hss
-   \aftergroup\egroup
-   \hss
-   \font_basics_switchtobodyfont\m_math_text_choice_face
-   #1%
-   \let\next}
+% %mathscriptboxmode    \plusthree % lists and boxes with \boundary=1 (also for testing and demo)
+% %mathscriptboxmode    \plusone   % collapsed and then removed, now control option
+% %mathscriptcharmode   \plusone   % idem
+%
+% %mathrulethicknessmode\plusone   % adaptive
 
-\def\math_text_choice_word#1#2#%
-  {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
-   \hbox#2\bgroup
-   \bgroup
-   \aftergroup\hss
-   \aftergroup\egroup
-   \hss
-   \font_basics_switchtobodyfont\m_math_text_choice_face
-   #1%
-   \nospacing % \normalnospaces\plusone
-   \let\next}
+% We keep this as reference:
+%
+% \def\math_text_choice_font#1#2#%
+%   {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
+%    \hbox#2\bgroup
+%    \bgroup
+%    \aftergroup\hss
+%    \aftergroup\egroup
+%    \hss
+%    \font_basics_switchtobodyfont\m_math_text_choice_face
+%    #1%
+%    \let\next}
+%
+% \def\math_text_choice_word#1#2#%
+%   {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
+%    \hbox#2\bgroup
+%    \bgroup
+%    \aftergroup\hss
+%    \aftergroup\egroup
+%    \hss
+%    \font_basics_switchtobodyfont\m_math_text_choice_face
+%    #1%
+%    \nospacing % \normalnospaces\plusone
+%    \let\next}
+%
+% % \ruledhbox{$\mathtext{abc ffi}$}
+% % \ruledhbox{$\mathword{abc ffi}$}
+%
+% \permanent\protected\def\mathtext  {\mathortext{\math_text_choice_font\relax}\hbox}
+% \permanent\protected\def\mathword  {\mathortext{\math_text_choice_word\relax}\hbox}
+%
+% \permanent\protected\def\mathtexttf{\mathortext{\math_text_choice_font\tf}\hbox}
+% \permanent\protected\def\mathtextit{\mathortext{\math_text_choice_font\it}\hbox}
+% \permanent\protected\def\mathtextsl{\mathortext{\math_text_choice_font\sl}\hbox}
+% \permanent\protected\def\mathtextbf{\mathortext{\math_text_choice_font\bf}\hbox}
+% \permanent\protected\def\mathtextbi{\mathortext{\math_text_choice_font\bi}\hbox}
+% \permanent\protected\def\mathtextbs{\mathortext{\math_text_choice_font\bs}\hbox}
+%
+% \permanent\protected\def\mathwordtf{\mathortext{\math_text_choice_word\tf}\hbox}
+% \permanent\protected\def\mathwordit{\mathortext{\math_text_choice_word\it}\hbox}
+% \permanent\protected\def\mathwordsl{\mathortext{\math_text_choice_word\sl}\hbox}
+% \permanent\protected\def\mathwordbf{\mathortext{\math_text_choice_word\bf}\hbox}
+% \permanent\protected\def\mathwordbi{\mathortext{\math_text_choice_word\bi}\hbox}
+% \permanent\protected\def\mathwordbs{\mathortext{\math_text_choice_word\bs}\hbox}
+
+%D The split option is sort or a gimmick but one never knows how it might come in
+%D handy. It was also an interesting test for how easy we can get this done (an extra
+%D option as well as cheating in the line break function). And it was a good excuse
+%D to add options to glue (which was pending). Actually, the main reason for this
+%D trickery was that unrolling lists into the main math list could have strange side
+%D effects, due to glue being ignored in math in the libereak routine, so better get
+%D it working than explaining why if could have side effects.
 
-% \ruledhbox{$\mathtext{abc ffi}$}
-% \ruledhbox{$\mathword{abc ffi}$}
+%D The fact that one can pass e.g \type {to 4cm} before the content is an old and
+%D probably never used feature that we keep in order to remain compatible.
 
-%mathscriptboxmode    \plusthree % lists and boxes with \boundary=1 (also for testing and demo)
-%mathscriptboxmode    \plusone   % collapsed and then removed, now control option
-%mathscriptcharmode   \plusone   % idem
+\installcorenamespace{mathtext}
 
-%mathrulethicknessmode\plusone   % adaptive
+\installcommandhandler \??mathtext {mathtext} \??mathtext
 
-\permanent\protected\def\mathtext  {\mathortext{\math_text_choice_font\relax}\hbox}
-\permanent\protected\def\mathword  {\mathortext{\math_text_choice_word\relax}\hbox}
+\setupmathtext
+  [\s!leftclass=\mathtextparameter\s!class,
+   \s!rightclass=\mathtextparameter\s!class,
+   \s!class=\mathordinarycode]
 
-\permanent\protected\def\mathtexttf{\mathortext{\math_text_choice_font\tf}\hbox}
-\permanent\protected\def\mathtextit{\mathortext{\math_text_choice_font\it}\hbox}
-\permanent\protected\def\mathtextsl{\mathortext{\math_text_choice_font\sl}\hbox}
-\permanent\protected\def\mathtextbf{\mathortext{\math_text_choice_font\bf}\hbox}
-\permanent\protected\def\mathtextbi{\mathortext{\math_text_choice_font\bi}\hbox}
-\permanent\protected\def\mathtextbs{\mathortext{\math_text_choice_font\bs}\hbox}
+\appendtoks
+    \frozen\protected\edefcsname\currentmathtext\endcsname{\math_text_handle{\currentmathtext}}
+\to \everydefinemathtext
+
+\newtoks\everymathtext
 
-\permanent\protected\def\mathwordtf{\mathortext{\math_text_choice_word\tf}\hbox}
-\permanent\protected\def\mathwordit{\mathortext{\math_text_choice_word\it}\hbox}
-\permanent\protected\def\mathwordsl{\mathortext{\math_text_choice_word\sl}\hbox}
-\permanent\protected\def\mathwordbf{\mathortext{\math_text_choice_word\bf}\hbox}
-\permanent\protected\def\mathwordbi{\mathortext{\math_text_choice_word\bi}\hbox}
-\permanent\protected\def\mathwordbs{\mathortext{\math_text_choice_word\bs}\hbox}
+\tolerant\protected\def\math_text_handle_indeed#1#*[#2]#:#3#%
+  {\begingroup
+   \edef\currentmathtext{#1}%
+   \setupcurrentmathtext[#2]%
+   \normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
+   \ifcstok{\mathtextparameter\c!alternative}\v!split
+     \mathatom
+       unroll
+       class      \mathtextparameter\s!class
+       leftclass  \mathtextparameter\s!leftclass
+       rightclass \mathtextparameter\s!rightclass
+       \bgroup
+     \hbox#3\bgroup
+     \aftergroup\egroup
+     \aftergroup\endgroup
+   \else
+     \hbox#3\bgroup
+     \atendofgroup\hss
+     \aftergroup\endgroup
+     \ifcstok{\mathtextparameter\c!alternative}\v!word
+       \nospacing % \normalnospaces\plusone
+     \fi
+     \hss
+   \fi
+   \font_basics_switchtobodyfont\m_math_text_choice_face
+   \usemathtextstyleandcolor\c!style\c!color
+   \the\everymathtext\relax
+   \let\next}
+
+\protected\def\math_text_handle#1%
+   {\mathortext{\math_text_handle_indeed{#1}}\hbox}
+
+\definemathtext[mathtext]
+\definemathtext[mathtexttf][mathtext][\c!style=\tf]
+\definemathtext[mathtextit][mathtext][\c!style=\it]
+\definemathtext[mathtextsl][mathtext][\c!style=\sl]
+\definemathtext[mathtextbf][mathtext][\c!style=\bf]
+\definemathtext[mathtextbi][mathtext][\c!style=\bi]
+\definemathtext[mathtextbs][mathtext][\c!style=\bs]
+
+\definemathtext[mathword]  [mathtext][\c!alternative=\v!word]
+\definemathtext[mathwordtf][mathword][\c!style=\tf]
+\definemathtext[mathwordit][mathword][\c!style=\it]
+\definemathtext[mathwordsl][mathword][\c!style=\sl]
+\definemathtext[mathwordbf][mathword][\c!style=\bf]
+\definemathtext[mathwordbi][mathword][\c!style=\bi]
+\definemathtext[mathwordbs][mathword][\c!style=\bs]
+
+\definemathtext[mathsplit]  [mathtext] [\c!alternative=\v!split]
+\definemathtext[mathsplittf][mathsplit][\c!style=\tf]
+\definemathtext[mathsplitit][mathsplit][\c!style=\it]
+\definemathtext[mathsplitsl][mathsplit][\c!style=\sl]
+\definemathtext[mathsplitbf][mathsplit][\c!style=\bf]
+\definemathtext[mathsplitbi][mathsplit][\c!style=\bi]
+\definemathtext[mathsplitbs][mathsplit][\c!style=\bs]
+
+\appendtoks
+    \reinstatecatcodecommand\barasciicode
+    \obeydiscretionaries
+\to \everymathtext
 
 %D Safeguard against redefinitions:
 
@@ -3773,7 +3960,7 @@
 
 \permanent\protected\def\math_scripts_unstack
   {\clf_enablescriptunstacking
-   \c_attr_mathunstack\plusone}
+   \c_attr_mathunstack\plustwo} % \plusone for the other way around
 
 \ifdefined\stackscripts   \else \aliased\let\stackscripts  \relax \fi
 \ifdefined\unstackscripts \else \aliased\let\unstackscripts\relax \fi
diff --git a/tex/context/base/mkxl/math-noa.lmt b/tex/context/base/mkxl/math-noa.lmt
index 3f77c2225..dfdfa6766 100644
--- a/tex/context/base/mkxl/math-noa.lmt
+++ b/tex/context/base/mkxl/math-noa.lmt
@@ -64,13 +64,7 @@ local trace_processing    = false  registertracker("math.processing",   function
 local trace_analyzing     = false  registertracker("math.analyzing",    function(v) trace_analyzing    = v end)
 local trace_normalizing   = false  registertracker("math.normalizing",  function(v) trace_normalizing  = v end)
 local trace_collapsing    = false  registertracker("math.collapsing",   function(v) trace_collapsing   = v end)
-local trace_fixing        = false  registertracker("math.fixing",       function(v) trace_fixing       = v end)
-local trace_patching      = false  registertracker("math.patching",     function(v) trace_patching     = v end)
 local trace_goodies       = false  registertracker("math.goodies",      function(v) trace_goodies      = v end)
-local trace_variants      = false  registertracker("math.variants",     function(v) trace_variants     = v end)
-local trace_alternates    = false  registertracker("math.alternates",   function(v) trace_alternates   = v end)
-local trace_italics       = false  registertracker("math.italics",      function(v) trace_italics      = v end)
-local trace_kernpairs     = false  registertracker("math.kernpairs",    function(v) trace_kernpairs    = v end)
 
 local check_coverage      = true   registerdirective("math.checkcoverage", function(v) check_coverage   = v     end)
 local use_math_goodies    = true   registerdirective("math.nogoodies",     function(v) use_math_goodies = not v end)
@@ -79,13 +73,7 @@ local report_processing   = logreporter("mathematics","processing")
 local report_remapping    = logreporter("mathematics","remapping")
 local report_normalizing  = logreporter("mathematics","normalizing")
 local report_collapsing   = logreporter("mathematics","collapsing")
-local report_fixing       = logreporter("mathematics","fixing")
-local report_patching     = logreporter("mathematics","patching")
 local report_goodies      = logreporter("mathematics","goodies")
-local report_variants     = logreporter("mathematics","variants")
-local report_alternates   = logreporter("mathematics","alternates")
-local report_italics      = logreporter("mathematics","italics")
-local report_kernpairs    = logreporter("mathematics","kernpairs")
 
 local a_mathrendering    = privateattribute("mathrendering")
 local a_exportstatus     = privateattribute("exportstatus")
@@ -113,6 +101,9 @@ local getfield           = nuts.getfield
 local getnext            = nuts.getnext
 local getprev            = nuts.getprev
 local getboth            = nuts.getboth
+local isnext             = nuts.isnext
+local isprev             = nuts.isprev
+local isboth             = nuts.isboth
 local getid              = nuts.getid
 local getsubtype         = nuts.getsubtype
 local getchar            = nuts.getchar
@@ -154,6 +145,9 @@ local setprime           = nuts.setprime
 local getoffsets         = nuts.getoffsets
 local setoffsets         = nuts.setoffsets
 
+local getoptions         = nuts.getoptions
+local setoptions         = nuts.setoptions
+
 local flushnode          = nuts.flush
 local copy_node          = nuts.copy
 local slide_nodes        = nuts.slide
@@ -202,25 +196,24 @@ local enableaction       = tasks.enableaction
 local setaction          = tasks.setaction
 
 local nodecodes          = nodes.nodecodes
-local noadcodes          = nodes.noadcodes
+----- noadcodes          = nodes.noadcodes
 local fencecodes         = nodes.fencecodes
-
-local ordinarynoad_code    = noadcodes.ordinary
-local operatornoad_code    = noadcodes.operator
-local binarynoad_code      = noadcodes.binary
-local relationnoad_code    = noadcodes.relation
-local opennoad_code        = noadcodes.open
-local closenoad_code       = noadcodes.close
-local middlenoad_code      = noadcodes.middle
-local punctuationnoad_code = noadcodes.punctuation
-local innernoad_code       = noadcodes.inner
-local fencednoad_code      = noadcodes.fenced
-local undernoad_code       = noadcodes.under
-local overnoad_code        = noadcodes.over
-local vcenternoad_code     = noadcodes.vcenter
-local fractionnoad_code    = noadcodes.fraction
-local radicalnoad_code     = noadcodes.radical
-local accentnoad_code      = noadcodes.accent
+local classes            = mathematics.classes -- or nodes.noadcodes
+
+local ordinary_class     = classes.ordinary
+local operator_class     = classes.operator
+local binary_class       = classes.binary
+local relation_class     = classes.relation
+local open_class         = classes.open
+local close_class        = classes.close
+local middle_class       = classes.middle
+local punctuation_class  = classes.punctuation
+local fenced_class       = classes.fenced
+local fraction_class     = classes.fraction
+local radical_class      = classes.radical
+local accent_class       = classes.accent
+local numbergroup_class  = classes.numbergroup
+local digit_class        = classes.digit
 
 local noad_code          = nodecodes.noad
 local accent_code        = nodecodes.accent
@@ -264,7 +257,7 @@ local function process(start,what,n,parent)
         local id = getid(start)
         if trace_processing then
             if id == noad_code then
-                report_processing("%w%S, class %a",n*2,nutstring(start),noadcodes[getsubtype(start)])
+                report_processing("%w%S, class %a",n*2,nutstring(start),classes[getsubtype(start)])
             elseif id == mathchar_code then
                 local char, font, fam = getcharspec(start)
                 report_processing("%w%S, family %a, font %a, char %a, shape %c",n*2,nutstring(start),fam,font,char,char)
@@ -680,7 +673,6 @@ do
 
     function handlers.families(head,style,penalties)
         processnoads(head,families,"families")
-        return true -- not needed
     end
 
 end
@@ -822,7 +814,6 @@ do
 
     function handlers.relocate(head,style,penalties)
         processnoads(head,relocate,"relocate")
-        return true -- not needed
     end
 
 end
@@ -855,7 +846,6 @@ do
 
     function handlers.render(head,style,penalties)
         processnoads(head,render,"render")
-        return true -- not needed
     end
 
 end
@@ -917,7 +907,6 @@ do
 
     function handlers.resize(head,style,penalties)
         processnoads(head,resize,"resize")
-        return true -- not needed
     end
 
 end
@@ -930,7 +919,7 @@ do
     local autofences      = { }
     local dummyfencechar  = 0x2E
 
-    local function makefence(what,char)
+    local function makefence(what,char,template)
         local d = new_delimiter() -- todo: attr
         local f = new_fence()     -- todo: attr
         if char then
@@ -943,8 +932,8 @@ do
             setfam(d,fam)
             flushnode(sym)
         end
-        setattrlist(d,char)
-        setattrlist(f,char)
+        setattrlist(d,template)
+        setattrlist(f,template)
         setsubtype(f,what)
         setfield(f,"delimiter",d)
         setfield(f,"class",-1) -- tex itself does this, so not fenceclasses[what]
@@ -972,8 +961,9 @@ do
 --     f_c    or "?"
 -- )
         local list = new_submlist()
-        setsubtype(noad,fencednoad_code)
+        setsubtype(noad,fenced_class)
         setnucleus(noad,list)
+        setattrlist(list,noad)
         setlist(list,f_o)
         setlink(f_o,o_next) -- prev of list is nil
         setlink(c_prev,f_c) -- next of list is nil
@@ -985,7 +975,7 @@ do
                 local midl = middle[current]
                 local next = getnext(current)
                 if midl then
-                    local fence = makefence(middlefence_code,current)
+                    local fence = makefence(middlefence_code,current,current)
                     setnucleus(current)
                     flushnode(current)
                     middle[current] = nil
@@ -1009,8 +999,8 @@ do
             return close
         else
             local c_prev, c_next = getboth(close)
-            local f_o = makefence(leftfence_code,open)
-            local f_c = makefence(rightfence_code,close)
+            local f_o = makefence(leftfence_code,open,open)
+            local f_c = makefence(rightfence_code,close,close)
             makelist(middle,open,f_o,o_next,c_prev,f_c)
             setnucleus(close)
             flushnode(close)
@@ -1021,8 +1011,8 @@ do
     end
 
     local function convert_open(open,last,middle) -- last is really last (final case)
-        local f_o = makefence(leftfence_code,open)
-        local f_c = makefence(rightfence_code)
+        local f_o = makefence(leftfence_code,open,open)
+        local f_c = makefence(rightfence_code,nil,open)
         local o_next = getnext(open)
         makelist(middle,open,f_o,o_next,last,nil)
         -- open is now a list
@@ -1031,7 +1021,7 @@ do
     end
 
     local function convert_close(first,close,middle)
-        local f_o = makefence(leftfence_code)
+        local f_o = makefence(leftfence_code,nil,close)
         local f_c = makefence(rightfence_code,close)
         local c_prev = getprev(close)
         local f_next = getnext(first)
@@ -1240,7 +1230,8 @@ do
             if start_super == stop_super then
                 setsup(pointer,getnucleus(start_super))
             else
-                local list = new_submlist() -- todo attr
+                local list = new_submlist()
+                setattrlist(list,pointer)
                 setlist(list,start_super)
                 setsup(pointer,list)
             end
@@ -1250,22 +1241,11 @@ do
             setnext(stop_super)
         end
         if start_sub then
-
---             if mode == "sub" then
---                 local sup = getsup(pointer)
---                 if sup and not getsub(pointer) then
---                     local nxt = getnext(pointer)
---                     local new = new_noad(pointer)
---                     setnucleus(new,new_submlist())
---                     setlink(pointer,new,nxt)
---                     pointer = new
---                 end
---             end
-
             if start_sub == stop_sub then
                 setsub(pointer,getnucleus(start_sub))
             else
-                local list = new_submlist() -- todo attr
+                local list = new_submlist()
+                setattrlist(list,pointer)
                 setlist(list,start_sub)
                 setsub(pointer,list)
             end
@@ -1281,7 +1261,6 @@ do
 
     function handlers.unscript(head,style,penalties)
         processnoads(head,unscript,"unscript")
-        return true -- not needed
     end
 
 end
@@ -1296,19 +1275,22 @@ do
     local report_unstacking = logreporter("mathematics","unstack")
 
     unstack[noad_code] = function(pointer)
-        if getattr(pointer,a_unstack) then
+        local a = getattr(pointer,a_unstack)
+        if a then
             local sup = getsup(pointer)
             local sub = getsub(pointer)
             if sup and sub then
              -- if trace_unstacking then
              --     report_unstacking() -- todo ... what to show ...
              -- end
-                local nxt = getnext(pointer)
-                local new = new_noad(pointer)
-                setnucleus(new,new_submlist())
-                setsub(pointer)
-                setsub(new,sub)
-                setlink(pointer,new,nxt)
+                if a == 1 then
+                    a = tex.noadoptioncodes.shiftedsubscript
+                elseif a == 2 then
+                    a = tex.noadoptioncodes.shiftedsuperscript
+                else
+                    a = 0
+                end
+                setoptions(pointer,getoptions(pointer) | a)
             end
         end
     end
@@ -1316,7 +1298,7 @@ do
     function handlers.unstack(head,style,penalties)
         if enabled then
             processnoads(head,unstack,"unstack")
-            return true -- not needed
+
         end
     end
 
@@ -1363,6 +1345,9 @@ end
 
 do
 
+    local trace_alternates  = false  registertracker("math.alternates", function(v) trace_alternates = v end)
+    local report_alternates = logreporter("mathematics","alternates")
+
     local last = 0
 
     local known = setmetatableindex(function(t,k)
@@ -1575,7 +1560,6 @@ do
 
     function handlers.alternates(head,style,penalties)
         processnoads(head,alternate,"alternate")
-        return true -- not needed
     end
 
 end
@@ -1595,129 +1579,160 @@ end
 -- some juggling that we want to avoid but we need to do something here (in fact, we could
 -- better fix the width of the character)
 
-do
-
-    local a_mathitalics = privateattribute("mathitalics")
-
-    local italics        = { }
-    local default_factor = 1/20
-
-    local setcolor     = colortracers.set
-    local resetcolor   = colortracers.reset
-    local italic_kern  = new_kern
-
-    local c_positive_d = "trace:dg"
-    local c_negative_d = "trace:dr"
-
-    local function insert_kern(current,kern)
-        local sub  = new_submlist() -- todo: attr
-        local noad = new_noad()     -- todo: attr
-        setlist(sub,kern)
-        setnext(kern,noad)
-        setnucleus(noad,current)
-        return sub
-    end
-
-    registertracker("math.italics.visualize", function(v)
-        if v then
-            italic_kern = function(k)
-                local n = new_kern(k) -- todo: attr
-                set_visual(n,"italic")
-                return n
-            end
-        else
-            italic_kern = new_kern
-        end
-    end)
-
-    local function getcorrection(method,font,char) -- -- or character.italic -- (this one is for tex)
-
-        local visual = chardata[char].visual
-
-        if method == 1 then
-            -- check on state
-            local italics = fontitalics[font]
-            if italics then
-                local character = fontcharacters[font][char]
-                if character then
-                    local correction = character.italic
-                    if correction and correction ~= 0 then
-                        return correction, visual
-                    end
-                end
-            end
-        elseif method == 2 then
-            -- no check
-            local character = fontcharacters[font][char]
-            if character then
-                local correction = character.italic
-                if correction and correction ~= 0 then
-                    return correction, visual
-                end
-            end
-        elseif method == 3 then
-            -- check on visual
-            if visual == "it" or visual == "bi" then
-                local character = fontcharacters[font][char]
-                if character then
-                    local correction = character.italic
-                    if correction and correction ~= 0 then
-                        return correction, visual
-                    end
-                end
-            end
-        elseif method == 4 then
-            -- combination of 1 and 3
-            local italics = fontitalics[font]
-            if italics and (visual == "it" or visual == "bi") then
-                local character = fontcharacters[font][char]
-                if character then
-                    local correction = character.italic
-                    if correction and correction ~= 0 then
-                        return correction, visual
-                    end
-                end
-            end
-        end
-
-    end
-
-    italics[mathchar_code] = function(pointer,what,n,parent)
-        local method = getattr(pointer,a_mathitalics)
-        if method and method > 0 and method < 100 then
-            local char, font = getcharspec(pointer)
-            local correction, visual = getcorrection(method,font,char)
-            if correction and correction ~= 0 then
-                local next_noad = getnext(parent)
-                if not next_noad then
-                    if n == 1 then
-                        -- only at the outer level .. will become an option (always,endonly,none)
-                        if trace_italics then
-                            report_italics("method %a, flagging italic correction %p between %C and end math",method,correction,char)
-                        end
-                        if correction > 0 then
-                            correction = correction + 100
-                        else
-                            correction = correction - 100
-                        end
-                        correction = round(correction)
-                        setattr(pointer,a_mathitalics,correction)
-                        setattr(parent,a_mathitalics,correction)
-                        return -- so no reset later on
-                    end
-                end
-            end
-        end
-        setattr(pointer,a_mathitalics,unsetvalue)
-    end
+-- do
+--
+--     local a_mathitalics  = privateattribute("mathitalics")
+--
+--     local trace_italics  = false  registertracker("math.italics", function(v) trace_italics = v end)
+--     local report_italics = logreporter("mathematics","italics")
+--
+--     local italics        = { }
+--
+--     local function getcorrection(method,font,char) -- -- or character.italic -- (this one is for tex)
+--
+--         local visual = chardata[char].visual
+--
+--         if method == 1 then
+--             -- check on state
+--             local italics = fontitalics[font]
+--             if italics then
+--                 local character = fontcharacters[font][char]
+--                 if character then
+--                     local correction = character.italic
+--                     if correction and correction ~= 0 then
+--                         return correction, visual
+--                     end
+--                 end
+--             end
+--         elseif method == 2 then
+--             -- no check
+--             local character = fontcharacters[font][char]
+--             if character then
+--                 local correction = character.italic
+--                 if correction and correction ~= 0 then
+--                     return correction, visual
+--                 end
+--             end
+--         elseif method == 3 then
+--             -- check on visual
+--             if visual == "it" or visual == "bi" then
+--                 local character = fontcharacters[font][char]
+--                 if character then
+--                     local correction = character.italic
+--                     if correction and correction ~= 0 then
+--                         return correction, visual
+--                     end
+--                 end
+--             end
+--         elseif method == 4 then
+--             -- combination of 1 and 3
+--             local italics = fontitalics[font]
+--             if italics and (visual == "it" or visual == "bi") then
+--                 local character = fontcharacters[font][char]
+--                 if character then
+--                     local correction = character.italic
+--                     if correction and correction ~= 0 then
+--                         return correction, visual
+--                     end
+--                 end
+--             end
+--         end
+--
+--     end
+--
+--     -- basically the engine should set it
+--
+--     italics[mathchar_code] = function(pointer,what,n,parent)
+--         local method = getattr(pointer,a_mathitalics)
+--         if method and method > 0 and method < 100 then
+--             local char, font = getcharspec(pointer)
+--             local correction, visual = getcorrection(method,font,char)
+--             if correction and correction ~= 0 then
+--                 local next_noad = getnext(parent)
+--                 if not next_noad then
+--                     if n == 1 then
+--                         -- only at the outer level .. will become an option (always,endonly,none)
+--                         if trace_italics then
+--                             report_italics("method %a, flagging italic correction %p between %C and end math",method,correction,char)
+--                         end
+--                         if correction > 0 then
+--                             correction = correction + 100
+--                         else
+--                             correction = correction - 100
+--                         end
+--                         correction = round(correction)
+--                         setattr(pointer,a_mathitalics,correction)
+--                         setattr(parent,a_mathitalics,correction)
+--                         return -- so no reset later on
+--                     end
+--                 end
+--             end
+--         end
+--         setattr(pointer,a_mathitalics,unsetvalue)
+--     end
+--
+--     function handlers.italics(head,style,penalties)
+--         processnoads(head,italics,"italics")
+--     end
+--
+--     local enable = function()
+--         enableaction("math", "noads.handlers.italics")
+--         if trace_italics then
+--             report_italics("enabling math italics")
+--         end
+--         -- we enable math (unless already enabled elsewhere)
+--         typesetters.italics.enablemath()
+--         enable = false
+--     end
+--
+--     -- best do this only on math mode (less overhead)
+--
+--     function mathematics.setitalics(name)
+--         if enable then
+--             enable()
+--         end
+--         texsetattribute(a_mathitalics,name and name ~= v_reset and tonumber(name) or unsetvalue) -- maybe also v_none
+--     end
+--
+--     function mathematics.getitalics(name)
+--         if enable then
+--             enable()
+--         end
+--         context(name and name ~= v_reset and tonumber(name) or unsetvalue)
+--     end
+--
+--     function mathematics.resetitalics()
+--         texsetattribute(a_mathitalics,unsetvalue)
+--     end
+--
+--     implement {
+--         name      = "initializemathitalics",
+--         actions   = enable,
+--         onlyonce  = true,
+--     }
+--
+--     implement {
+--         name      = "setmathitalics",
+--         actions   = mathematics.setitalics,
+--         arguments = "string",
+--     }
+--
+--     implement {
+--         name      = "getmathitalics",
+--         actions   = mathematics.getitalics,
+--         arguments = "string",
+--     }
+--
+--     implement {
+--         name      = "resetmathitalics",
+--         actions   = mathematics.resetitalics
+--     }
+--
+-- end
 
-    function handlers.italics(head,style,penalties)
-        processnoads(head,italics,"italics")
-        return true -- not needed
-    end
+do
 
     local enable = function()
-        enableaction("math", "noads.handlers.italics")
         if trace_italics then
             report_italics("enabling math italics")
         end
@@ -1726,49 +1741,12 @@ do
         enable = false
     end
 
-    -- best do this only on math mode (less overhead)
-
-    function mathematics.setitalics(name)
-        if enable then
-            enable()
-        end
-        texsetattribute(a_mathitalics,name and name ~= v_reset and tonumber(name) or unsetvalue) -- maybe also v_none
-    end
-
-    function mathematics.getitalics(name)
-        if enable then
-            enable()
-        end
-        context(name and name ~= v_reset and tonumber(name) or unsetvalue)
-    end
-
-    function mathematics.resetitalics()
-        texsetattribute(a_mathitalics,unsetvalue)
-    end
-
     implement {
         name      = "initializemathitalics",
         actions   = enable,
         onlyonce  = true,
     }
 
-    implement {
-        name      = "setmathitalics",
-        actions   = mathematics.setitalics,
-        arguments = "string",
-    }
-
-    implement {
-        name      = "getmathitalics",
-        actions   = mathematics.getitalics,
-        arguments = "string",
-    }
-
-    implement {
-        name      = "resetmathitalics",
-        actions   = mathematics.resetitalics
-    }
-
 end
 
 do
@@ -1786,6 +1764,9 @@ do
     local a_kernpairs = privateattribute("mathkernpairs")
     local kernpairs   = { }
 
+    local trace_kernpairs  = false  registertracker("math.kernpairs", function(v) trace_kernpairs = v end)
+    local report_kernpairs = logreporter("mathematics","kernpairs")
+
     local function enable()
         enableaction("math", "noads.handlers.kernpairs")
         if trace_kernpairs then
@@ -1817,10 +1798,10 @@ do
             if list then
                 local found = list[first]
                 if found then
-                    local next = getnext(parent)
-                    if next and getid(next) == noad_code then
-                        pointer = getnucleus(next)
-                        if pointer then
+                    local next = isnext(parent,noad_code)
+                    if next then
+--                         pointer = getnucleus(next)
+--                         if pointer then
                             local second, secondfont = getcharspec(pointer)
                             if secondfont == firstfont then
                                 local kern = found[second]
@@ -1829,10 +1810,12 @@ do
                                     if trace_kernpairs then
                                         report_kernpairs("adding %p kerning between %C and %C",kern,first,second)
                                     end
-                                    setlink(parent,new_kern(kern),getnext(parent)) -- todo: attr
+                                    kern = new_kern(kern)
+                                    setlink(parent,kern,getnext(parent))
+                                    setattrlist(kern,pointer)
                                 end
                             end
-                        end
+--                         end
                     end
                 end
             end
@@ -1843,11 +1826,164 @@ do
         if use_math_goodies then
             processnoads(head,kernpairs,"kernpairs")
         end
-        return true -- not needed
     end
 
 end
 
+do
+
+    local a_numbers = privateattribute("mathnumbers")
+    local a_spacing = privateattribute("mathspacing")
+
+    local numbers   = { }
+    local spacing   = { }
+
+    local separators = {
+        [0x2E] = { 0x2E, 0x2C, 0x002E, 0x002C, 0x2008, 0x2008 }, -- . -- punctuationspace
+        [0x2C] = { 0x2C, 0x2E, 0x2008, 0x2008, 0x002E, 0x002C }, -- ,
+    }
+
+    local digits = {
+        [0x30] = true, [0x31] = true,
+        [0x32] = true, [0x33] = true,
+        [0x34] = true, [0x35] = true,
+        [0x36] = true, [0x37] = true,
+        [0x38] = true, [0x39] = true,
+    }
+
+    local snoloc = {
+        [punctuation_class] = 0x003A,
+        [relation_class]    = 0x2236,
+    }
+
+    local colons = {
+        [0x003A] = snoloc,
+        [0x2236] = snoloc,
+    }
+
+    local followedbyspace_code = tex.noadoptioncodes.followedbyspace
+
+    local function followedbyspace(n)
+        return getoptions(n) & followedbyspace_code == followedbyspace_code
+    end
+
+    numbers[mathchar_code] = function(pointer,what,n,parent)
+        local alternative = getattr(pointer,a_numbers)
+        if alternative then
+            local oldchar = getcharspec(pointer)
+            local found   = separators[oldchar]
+            if found then
+                local prev, next = isboth(parent,noad_code)
+                if prev and next then
+                 -- local lc = getcharspec(getnucleus(prev))
+                    local lc = getcharspec(prev)
+                    if digits[lc] then
+                     -- local rc = getcharspec(getnucleus(next))
+                        local rc = getcharspec(next)
+                        if digits[rc] then
+                            local newchar = found[alternative]
+                            local class   = followedbyspace(parent) and punctuation_class or ordinary_class
+                            setsubtype(parent,class)
+                            if newchar ~= oldchar then
+                                setchar(pointer,newchar)
+                            end
+                         -- if trace_numbers then
+                         --     report_numbers("digit separator digit")
+                         -- end
+                        end
+                    end
+                end
+                return
+            end
+            found = digits[oldchar]
+            if found then
+                if followedbyspace(parent) then
+                    local next = isnext(parent,noad_code)
+                    if next then
+                 --     local rc = getcharspec(getnucleus(next))
+                        local rc = getcharspec(next)
+                        if rc and digits[rc] then
+                            local n = new_noad(numbergroup_class)
+                            local s = new_submlist()
+                            setnucleus(n,s)
+                            setattrlist(n,pointer)
+                            setattrlist(s,pointer)
+                            setlink(parent,n,next)
+                         -- if trace_numbers then
+                         --     report_numbers("digit spacer digit")
+                         -- end
+                        end
+                    end
+                end
+                return
+            end
+        end
+    end
+
+    spacing[mathchar_code] = function(pointer,what,n,parent)
+        if getattr(pointer,a_spacing) then
+            local oldchar = getcharspec(pointer)
+            local found   = colons[oldchar]
+            if found then
+                local prev = isprev(parent,noad_code)
+                if prev then
+                    local class   = followedbyspace(prev) and relation_class or punctuation_class
+                    local newchar = found[class]
+                    setsubtype(parent,class)
+                    if newchar ~= oldchar then
+                        setchar(pointer,newchar)
+                    end
+                 -- if trace_spacing then
+                 --     report_spacinf("spacer colon")
+                 -- end
+                end
+                return
+            end
+        end
+    end
+
+    -- numbers
+
+    function handlers.numbers(head,style,penalties)
+        processnoads(head,numbers,"numbers")
+    end
+
+    local enable = function()
+        enableaction("math", "noads.handlers.numbers")
+     -- if trace_numbers then
+     --     report_numbers("enabling math numbers")
+     -- end
+        enable = false
+    end
+
+    implement {
+        name     = "initializemathnumbers",
+        actions  = enable,
+        onlyonce = true,
+    }
+
+    -- spacing
+
+    function handlers.spacing(head,style,penalties)
+        processnoads(head,spacing,"spacing")
+    end
+
+    local enable = function()
+        enableaction("math", "noads.handlers.spacing")
+     -- if trace_numbers then
+     --     report_spacing("enabling math spacinf")
+     -- end
+        enable = false
+    end
+
+    implement {
+        name     = "initializemathspacing",
+        actions  = enable,
+        onlyonce = true,
+    }
+
+end
+
 -- primes and such
 
 do
@@ -1858,28 +1994,21 @@ do
     local collapse         = { }
     local mathlists        = characters.mathlists
     local validpair        = {
-        [ordinarynoad_code]    = true,
-        [operatornoad_code]    = true,
-        [binarynoad_code]      = true, -- new
-        [relationnoad_code]    = true,
-        [opennoad_code]        = true, -- new
-        [middlenoad_code]      = true, -- new
-        [closenoad_code]       = true, -- new
-        [punctuationnoad_code] = true, -- new
-        [innernoad_code]       = false,
-        [fencednoad_code]      = false,
-        [undernoad_code]       = false,
-        [overnoad_code]        = false,
-        [vcenternoad_code]     = false,
-        [fractionnoad_code]    = true,
-        [radicalnoad_code]     = false,
-        [accentnoad_code]      = true,
+        [ordinary_class]    = true,
+        [operator_class]    = true,
+        [binary_class]      = true, -- new
+        [relation_class]    = true,
+        [open_class]        = true, -- new
+        [middle_class]      = true, -- new
+        [close_class]       = true, -- new
+        [punctuation_class] = true, -- new
+        [fraction_class]    = true,
+        [accent_class]      = true,
     }
 
     local reported = setmetatableindex("table")
 
     collapse[mathchar_code] = function(pointer,what,n,parent)
-
         if parent and mathlists[getchar(pointer)] then
             local found, last, lucleus, lsup, lsub, category
             local tree    = mathlists
@@ -1963,7 +2092,6 @@ do
 
     function noads.handlers.collapse(head,style,penalties)
         processnoads(head,collapse,"collapse")
-        return true -- not needed
     end
 
     local enable = function()
@@ -1975,9 +2103,9 @@ do
     end
 
     implement {
-        name      = "initializemathcollapsing",
-        actions   = enable,
-        onlyonce  = true,
+        name     = "initializemathcollapsing",
+        actions  = enable,
+        onlyonce = true,
     }
 
 end
@@ -2049,7 +2177,6 @@ do
 
     function noads.handlers.fixscripts(head,style,penalties)
         processnoads(head,fixscripts,"fixscripts")
-        return true -- not needed
     end
 
 end
@@ -2062,6 +2189,9 @@ do
     local chardata  = characters.data
     local a_variant = privateattribute("mathvariant")
 
+    local trace_variants  = false  registertracker("math.variants", function(v) trace_variants = v end)
+    local report_variants = logreporter("mathematics","variants")
+
     local function setvariant(pointer,selector,char)
         local tfmdata      = fontdata[getfont(pointer)]
         local mathvariants = tfmdata.resources.variants -- and variantdata / can be a hash
@@ -2090,8 +2220,8 @@ do
         if data then
             local variants = data.variants
             if variants then
-                local next = getnext(parent)
-                if next and getid(next) == noad_code then
+                local next = isnext(parent,noad_code)
+                if next then
                     local nucleus = getnucleus(next)
                     if nucleus and getid(nucleus) == mathchar_code then
                         local selector = getchar(nucleus)
@@ -2138,7 +2268,6 @@ do
 
     function handlers.variants(head,style,penalties)
         processnoads(head,variants,"unicode variant")
-        return true -- not needed
     end
 
     local valid = {
@@ -2171,21 +2300,13 @@ do
 
     local classes = { }
     local colors  = {
-        [relationnoad_code]    = "trace:dr",
-        [ordinarynoad_code]    = "trace:db",
-        [binarynoad_code]      = "trace:dg",
-        [opennoad_code]        = "trace:dm",
-        [middlenoad_code]      = "trace:dm",
-        [closenoad_code]       = "trace:dm",
-        [punctuationnoad_code] = "trace:dc",
-     -- [operatornoad_code]    = "",
-     -- [innernoad_code        = "",
-     -- [fencednoad_code       = "",
-     -- [undernoad_code]       = "",
-     -- [overnoad_code]        = "",
-     -- [vcenternoad_code]     = "",
-     -- [fractionnoad_code]    = "",
-     -- [radicalnoad_code]     = "",
+        [relation_class]    = "trace:dr",
+        [ordinary_class]    = "trace:db",
+        [binary_class]      = "trace:dg",
+        [open_class]        = "trace:dm",
+        [middle_class]      = "trace:dm",
+        [close_class]       = "trace:dm",
+        [punctuation_class] = "trace:dc",
     }
 
     local setcolor   = colortracers.set
@@ -2202,7 +2323,6 @@ do
 
     function handlers.classes(head,style,penalties)
         processnoads(head,classes,"classes")
-        return true -- not needed
     end
 
     registertracker("math.classes",function(v)
@@ -2414,14 +2534,14 @@ end
 --     local a_mathdomain  = privateattribute("mathdomain")
 --     mathematics.domains = categories
 --     local permitted     = {
---         ordinary    = ordinarynoad_code,
---         binary      = binarynoad_code,
---         relation    = relationnoad_code,
---         punctuation = punctuationnoad_code,
+--         ordinary    = ordinary_class,
+--         binary      = binary_class,
+--         relation    = relation_class,
+--         punctuation = punctuation_class,
 --         inner       = innernoad_code,
---         fenced      = fencednoad_code,
---      -- fraction    = fractionnoad_code,
---      -- radical     = radicalnoad_code,
+--         fenced      = fenced_class,
+--      -- fraction    = fraction_class,
+--      -- radical     = radical_class,
 --     }
 --
 --     function mathematics.registerdomain(data)
@@ -2551,7 +2671,6 @@ end
 --
 --     function handlers.domains(head,style,penalties)
 --         processnoads(head,domains,"domains")
---         return true -- not needed
 --     end
 --
 -- end
@@ -2672,9 +2791,9 @@ do
     local suspicious = { }  noads.processors.suspicious = suspicious
 
     local candidates = {
-        [mathematics.classes.maybeordinary] = "maybeordinary",
-        [mathematics.classes.mayberelation] = "mayberelation",
-        [mathematics.classes.maybebinary  ] = "maybebinary",
+        [classes.maybeordinary] = "maybeordinary",
+        [classes.mayberelation] = "mayberelation",
+        [classes.maybebinary  ] = "maybebinary",
     }
     local registered = setmetatableindex("table")
 
diff --git a/tex/context/base/mkxl/math-rad.mklx b/tex/context/base/mkxl/math-rad.mklx
index caa58b9d0..04d6bfbba 100644
--- a/tex/context/base/mkxl/math-rad.mklx
+++ b/tex/context/base/mkxl/math-rad.mklx
@@ -337,23 +337,28 @@
 %
 % \dorecurse{8}{$\mathhat{\blackrule[width=#1ex,color=gray]}$ }
 
+% \annuity {(x+1)} \Uchar"20E7
+
+\integerdef\delimitedleftanutityuc  \privatecharactercode{delimited left annuity}
+\integerdef\delimitedrightanutityuc \privatecharactercode{delimited right annuity}
+
 \definemathradical
   [rannuity]
   [\c!left=\zerocount,
-   \c!right="20E7,
+   \c!right=\delimitedrightanutityuc,
    \c!rightmargin=.05\emwidth]
 
 \definemathradical
   [lannuity]
-  [\c!left="FE942,
+  [\c!left=\delimitedleftanutityuc,
    \c!right=\zerocount,
    \c!leftmargin=.05\emwidth,
    \c!rightmargin=.05\emwidth]
 
 \definemathradical
   [lrannuity]
-  [\c!left="FE942,
-   \c!right="20E7,
+  [\c!left=\delimitedleftanutityuc,
+   \c!right=\delimitedrightanutityuc,
    \c!leftmargin=.05\emwidth,
    \c!rightmargin=.05\emwidth]
 
diff --git a/tex/context/base/mkxl/node-nut.lmt b/tex/context/base/mkxl/node-nut.lmt
index a2a0043ac..62b733125 100644
--- a/tex/context/base/mkxl/node-nut.lmt
+++ b/tex/context/base/mkxl/node-nut.lmt
@@ -89,6 +89,7 @@ local nuts = {
     getchardict             = direct.getchardict,
     getcharspec             = direct.getcharspec,
     getchoice               = direct.getchoice,
+    getclass                = direct.getclass,
     getdata                 = direct.getdata,
     getdegree               = direct.getdegree,
     getdelimiter            = direct.getdelimiter,
@@ -180,6 +181,9 @@ local nuts = {
     isprevchar              = direct.isprevchar,
     isprevglyph             = direct.isprevglyph,
     iszeroglue              = direct.iszeroglue,
+    isnext                  = direct.isnext,
+    isprev                  = direct.isprev,
+    isboth                  = direct.isboth,
     kerning                 = direct.kerning,
     lastnode                = direct.lastnode,
     length                  = direct.length,
@@ -215,6 +219,7 @@ local nuts = {
     setchar                 = direct.setchar,
     setchardict             = direct.setchardict,
     setchoice               = direct.setchoice,
+    setclass                = direct.setclass,
     setdata                 = direct.setdata,
     setdegree               = direct.setdegree,
     setdelimiter            = direct.setdelimiter,
diff --git a/tex/context/base/mkxl/node-res.lmt b/tex/context/base/mkxl/node-res.lmt
index 672f3c5a5..5b7ac3fb5 100644
--- a/tex/context/base/mkxl/node-res.lmt
+++ b/tex/context/base/mkxl/node-res.lmt
@@ -73,6 +73,7 @@ local setshift     = nuts.setshift
 local setwidth     = nuts.setwidth
 local setsubtype   = nuts.setsubtype
 local setleader    = nuts.setleader
+local setclass     = nuts.setclass
 
 local setdata      = nuts.setdata
 local setruledata  = nuts.setruledata
@@ -452,11 +453,18 @@ function nutpool.temp()
     return copy_nut(temp)
 end
 
-function nutpool.noad()         return copy_nut(noad)         end
+function nutpool.noad(class)
+    local n = copy_nut(noad)
+    if class then
+        setsubtype(n,class)
+        setclass(n,class,class,class)
+    end
+    return n
+end
+
 function nutpool.delimiter()    return copy_nut(delimiter)    end  nutpool.delim = nutpool.delimiter
 function nutpool.fence()        return copy_nut(fence)        end
 function nutpool.submlist()     return copy_nut(submlist)     end
-function nutpool.noad()         return copy_nut(noad)         end
 function nutpool.fence()        return copy_nut(fence)        end
 function nutpool.accent()       return copy_nut(accent)       end
 function nutpool.radical()      return copy_nut(radical)      end
diff --git a/tex/context/base/mkxl/node-rul.mkxl b/tex/context/base/mkxl/node-rul.mkxl
index ac66d11b3..ec9003f58 100644
--- a/tex/context/base/mkxl/node-rul.mkxl
+++ b/tex/context/base/mkxl/node-rul.mkxl
@@ -96,10 +96,10 @@
 \protected\def\node_rules_direct#1%
   {\groupedcommand
      {\dontleavehmode % this should not be needed but it is in \bTD
-      \node_rules_set{#1}
+      \node_rules_set{#1}%
       \barparameter\c!left
-      } %\ignorespaces}%
-     {%\removeunwantesspaces
+      }%\ignorespaces}%
+     {%\removeunwantedspaces
       \barparameter\c!right}}
 
 \permanent\protected\def\inlinebar[#1]%
diff --git a/tex/context/base/mkxl/node-shp.lmt b/tex/context/base/mkxl/node-shp.lmt
index 7848c623e..7d73d9390 100644
--- a/tex/context/base/mkxl/node-shp.lmt
+++ b/tex/context/base/mkxl/node-shp.lmt
@@ -49,17 +49,17 @@ do
 
     local report  = logs.reporter("shipout")
 
-    local trace   = false  trackers.register("backend", "cleanup", function(v) trace = v end)
+    local trace   = false  trackers.register("backend.cleanup", function(v) trace = v end)
 
-    local flatten = true -- always true
+    local flatten = true -- also done as line option
     local soften  = true -- true by default
 
     nodes.handlers.cleanuppage = function(head)
-        local count    = 0
+     -- local count    = 0
         local found    = 0
         local replaced = 0
         if flatten then
-            head, count = flattendiscretionaries(head)
+            head, count = flattendiscretionaries(head,true) -- nested
         end
         if soften then
             head, found, replaced = softenhyphens(head) -- could have been a lua loop
diff --git a/tex/context/base/mkxl/pack-box.mkxl b/tex/context/base/mkxl/pack-box.mkxl
index 43f6bfbc7..28c1a42f0 100644
--- a/tex/context/base/mkxl/pack-box.mkxl
+++ b/tex/context/base/mkxl/pack-box.mkxl
@@ -1150,30 +1150,14 @@
    \defineoverlay[#1:\v!background][\overlayanchorbox{#1:\v!background}]%
    \defineoverlay[#1:\v!foreground][\overlayanchorbox{#1:\v!foreground}]}
 
-\permanent\def\namedboxanchor#1%
-  {\csname\??boxanchorid#1\endcsname} % no checking
-
-% \permanent\protected\def\overlayanchorbox#1%
-%   {\begingroup
-%    \scratchcounter\csname\??boxanchorbox#1\endcsname
-%    \ifvoid\scratchcounter\else
-%      \setbox\scratchbox\hpack \s!source \namedboxanchor{#1}\bgroup
-%    % \setbox\scratchbox\hpack\bgroup
-%        \box\scratchcounter
-%      \egroup
-%    % \boxsource\scratchbox\namedboxanchor{#1}%
-%      \wd\scratchbox\overlaywidth
-%      \ht\scratchbox\overlayheight
-%      \dp\scratchbox\overlaydepth
-%      \box\scratchbox
-%    \fi
-%    \endgroup}
+\permanent\def\namedanchorbox#1%
+  {\begincsname\??boxanchorid#1\endcsname} % no checking
 
 \permanent\protected\def\overlayanchorbox#1%
   {\begingroup
    \scratchcounter\csname\??boxanchorbox#1\endcsname
    \ifvoid\scratchcounter\else
-     \boxsource\scratchcounter\namedboxanchor{#1}%
+     \boxsource\scratchcounter\namedanchorbox{#1}%
      \wd\scratchcounter\d_overlay_width
      \ht\scratchcounter\d_overlay_height
      \dp\scratchcounter\d_overlay_depth
@@ -1189,20 +1173,24 @@
       \scratchcounterone\csname\??boxanchorbox#1\endcsname\relax
       \scratchxoffset\boxanchorparameter\c!xoffset\relax
       \scratchyoffset\boxanchorparameter\c!yoffset\relax
-      \boxtarget\nextbox \namedboxanchor {#1}\relax
+      \boxtarget\nextbox \namedanchorbox {#1}\relax
       \boxanchors\nextbox
         % target
-        \ifcsname\??boxpreset\boxanchorparameter\c!target\endcsname
-          \lastnamedcs
-        \else
-          \halfwaytotallistanchorcode
-        \fi
+        \numexpr
+          \ifcsname\??boxpreset\boxanchorparameter\c!target\endcsname
+            \lastnamedcs
+          \else
+            \halfwaytotallistanchorcode
+          \fi
+        \relax
         % source
-        \ifcsname\??boxpreset\boxanchorparameter\c!source\endcsname
-          \lastnamedcs
-        \else
-          \halfwaytotallistanchorcode
-        \fi
+        \numexpr
+          \ifcsname\??boxpreset\boxanchorparameter\c!source\endcsname
+            \lastnamedcs
+          \else
+            \halfwaytotallistanchorcode
+          \fi
+        \relax
       \ifdim\scratchxoffset=\zeropoint\else
          \boxxoffset\nextbox\scratchxoffset
       \fi
diff --git a/tex/context/base/mkxl/task-ini.lmt b/tex/context/base/mkxl/task-ini.lmt
index 0cb473651..862192c83 100644
--- a/tex/context/base/mkxl/task-ini.lmt
+++ b/tex/context/base/mkxl/task-ini.lmt
@@ -98,6 +98,8 @@ appendaction("shipouts",     "wrapup",      "nodes.handlers.export",
 appendaction("shipouts",     "wrapup",      "luatex.synctex.collect",                           nil, "nut",    "disabled"  )
 
 appendaction("math",         "normalizers", "noads.handlers.showtree",                          nil, "nonut",  "disabled"  )
+appendaction("math",         "normalizers", "noads.handlers.numbers",                           nil, "nonut",  "disabled"  )
+appendaction("math",         "normalizers", "noads.handlers.spacing",                           nil, "nonut",  "disabled"  )
 appendaction("math",         "normalizers", "noads.handlers.unscript",                          nil, "nonut",  "enabled"   )
 appendaction("math",         "normalizers", "noads.handlers.unstack",                           nil, "nonut",  "disabled"  )
 appendaction("math",         "normalizers", "noads.handlers.relocate",                          nil, "nonut",  "enabled"   )
@@ -112,7 +114,7 @@ appendaction("math",         "normalizers", "noads.handlers.resize",
 ------------("math",         "normalizers", "noads.handlers.respace",                           nil, "nonut",  "enabled"   )
 appendaction("math",         "normalizers", "noads.handlers.alternates",                        nil, "nonut",  "enabled"   )
 appendaction("math",         "normalizers", "noads.handlers.tags",                              nil, "nonut",  "disabled"  )
-appendaction("math",         "normalizers", "noads.handlers.italics",                           nil, "nonut",  "disabled"  )
+------------("math",         "normalizers", "noads.handlers.italics",                           nil, "nonut",  "disabled"  )  -- replaced
 appendaction("math",         "normalizers", "noads.handlers.kernpairs",                         nil, "nonut",  "disabled"  )
 appendaction("math",         "normalizers", "noads.handlers.classes",                           nil, "nonut",  "disabled"  )
 appendaction("math",         "normalizers", "noads.handlers.dictionaries",                      nil, "nonut",  "enabled"   )
diff --git a/tex/context/base/mkxl/typo-cap.lmt b/tex/context/base/mkxl/typo-cap.lmt
index 4a55c410f..5d7dfdedb 100644
--- a/tex/context/base/mkxl/typo-cap.lmt
+++ b/tex/context/base/mkxl/typo-cap.lmt
@@ -38,7 +38,7 @@ local copy_node       = nuts.copy
 local endofmath       = nuts.endofmath
 local insertafter     = nuts.insertafter
 local findattribute   = nuts.findattribute
-local unsetattributes = nuts.unsetattributes
+----- unsetattributes = nuts.unsetattributes
 
 local nextglyph       = nuts.traversers.glyph
 
diff --git a/tex/context/base/mkxl/typo-itc.lmt b/tex/context/base/mkxl/typo-itc.lmt
index dd7945eab..f2f6c428e 100644
--- a/tex/context/base/mkxl/typo-itc.lmt
+++ b/tex/context/base/mkxl/typo-itc.lmt
@@ -6,17 +6,22 @@ if not modules then modules = { } end modules ['typo-itc'] = {
     license   = "see context related readme files"
 }
 
+-- very old code ...
+
 local tonumber = tonumber
 
 local trace_italics       = false  trackers.register("typesetters.italics", function(v) trace_italics = v end)
 
 local report_italics      = logs.reporter("nodes","italics")
 
-local threshold           = 0.5   trackers.register("typesetters.threshold", function(v) threshold = v == true and 0.5 or tonumber(v) end)
+local threshold           = 0.5   directives.register("typesetters.italics.threshold", function(v) threshold = v == true and 0.5 or tonumber(v) end)
 
 typesetters.italics       = typesetters.italics or { }
 local italics             = typesetters.italics
 
+local variables           = interfaces.variables
+local settings_to_hash    = utilities.parsers.settings_to_hash
+
 local nodecodes           = nodes.nodecodes
 local glyph_code          = nodecodes.glyph
 local kern_code           = nodecodes.kern
@@ -120,11 +125,11 @@ end
 -- todo: clear attribute
 
 local function correction_okay(n)
-    return not (getoptions(n) & no_correction_code)
+    return not (getoptions(n) & no_correction_code == no_correction_code)
 end
 
 local function okay(data,current,font,prevchar,previtalic,char,what)
-    if getoptions(current) & no_correction_code then
+    if getoptions(current) & no_correction_code == no_correction_code then
         if trace_italics then
             report_italics("ignoring %p between %s italic %C and italic %C, %s",previtalic,what,prevchar,char,"disabled")
         end
@@ -203,7 +208,8 @@ local function domath(head,current)
         local char, id = isglyph(next)
         if char and correction_okay(next) then
             -- we can have an old font where italic correction has been applied
-            -- or a new one where it hasn't been done
+            -- or a new one where it hasn't been done ... actually, we now always
+            -- have one under detailed engine control
             local kern = getprev(current)
             if kern and getid(kern) == kern_code then
                 local glyph = getprev(kern)
@@ -212,12 +218,7 @@ local function domath(head,current)
                     -- punctuation
                     if is_punctuation[char] then
                         local a = getattr(glyph,a_mathitalics)
-                        if a and (a < 100 or a > 100) then
-                            if a > 100 then
-                                a = a - 100
-                            else
-                                a = a + 100
-                            end
+                        if a then
                             local i = getkern(kern)
                             local c, f = isglyph(glyph)
                             if getheight(next) < 1.25*exheights[f] then
@@ -231,45 +232,45 @@ local function domath(head,current)
                                     end
                                     setkern(kern,0) -- or maybe a small value or half the ic
                                 end
-                            elseif i == 0 then
-                                local d = chardata[f][c]
-                                local i = d.italic
-                                if i == 0 then
-                                    if trace_italics then
-                                        report_italics("%s italic %p between math %C and punctuation %C","ignoring",i,c,char)
-                                    end
-                                else
-                                    setkern(kern,i)
-                                    if trace_italics then
-                                        report_italics("%s italic %p between math %C and punctuation %C","setting",i,c,char)
-                                    end
-                                end
+                         -- elseif i == 0 then
+                         --     local d = chardata[f][c]
+                         --     local i = d.italic
+                         --     if i == 0 then
+                         --         if trace_italics then
+                         --             report_italics("%s italic %p between math %C and punctuation %C","ignoring",i,c,char)
+                         --         end
+                         --     else
+                         --         setkern(kern,i)
+                         --         if trace_italics then
+                         --             report_italics("%s italic %p between math %C and punctuation %C","setting",i,c,char)
+                         --         end
+                         --     end
                             elseif trace_italics then
                                 report_italics("%s italic %p between math %C and punctuation %C","keeping",k,c,char)
                             end
                         end
                     end
                 end
-            else
-                local glyph = kern
-                if glyph and getid(glyph) == glyph_code then
-                    -- [math: <glyph>]<glyph> : we add the correction when we have
-                    -- no punctuation
-                    if not is_punctuation[char] then
-                        local a = getattr(glyph,a_mathitalics)
-                        if a and (a < 100 or a > 100) then
-                            if a > 100 then
-                                a = a - 100
-                            else
-                                a = a + 100
-                            end
-                            if trace_italics then
-                                report_italics("%s italic %p between math %C and non punctuation %C","adding",a,getchar(glyph),char)
-                            end
-                            insertnodeafter(head,glyph,correction_kern(a,glyph))
-                        end
-                    end
-                end
+         -- else
+         --     local glyph = kern
+         --     if glyph and getid(glyph) == glyph_code then
+         --         -- [math: <glyph>]<glyph> : we add the correction when we have
+         --         -- no punctuation
+         --         if not is_punctuation[char] then
+         --             local a = getattr(glyph,a_mathitalics)
+         --             if a and (a < 100 or a > 100) then
+         --                 if a > 100 then
+         --                     a = a - 100
+         --                 else
+         --                     a = a + 100
+         --                 end
+         --                 if trace_italics then
+         --                     report_italics("%s italic %p between math %C and non punctuation %C","adding",a,getchar(glyph),char)
+         --                 end
+         --                 insertnodeafter(head,glyph,correction_kern(a,glyph))
+         --             end
+         --         end
+         --     end
             end
         end
     end
@@ -668,9 +669,6 @@ implement {
     actions   = italics.reset,
 }
 
-local variables        = interfaces.variables
-local settings_to_hash = utilities.parsers.settings_to_hash
-
 local function setupitaliccorrection(option) -- no grouping !
     if enabletext then
         enabletext()
diff --git a/tex/context/base/mkxl/typo-rub.lmt b/tex/context/base/mkxl/typo-rub.lmt
index f5bba7f7f..0de0221ef 100644
--- a/tex/context/base/mkxl/typo-rub.lmt
+++ b/tex/context/base/mkxl/typo-rub.lmt
@@ -73,6 +73,8 @@ local new_kern        = nodepool.kern
 local setprop         = nuts.setprop
 local getprop         = nuts.getprop
 
+local findattribute   = nuts.findattribute
+
 local enableaction    = nodes.tasks.enableaction
 
 local nofrubies       = 0
@@ -86,6 +88,12 @@ typesetters.rubies    = rubies
 local trace_rubies    = false  trackers.register("typesetters.rubies",function(v) trace_rubies = v end)
 local report_rubies   = logs.reporter("rubies")
 
+-- todo: use the more modern lmtx storage model
+
+local registervalue   = attributes.registervalue
+local getvalue        = attributes.getvalue
+local texsetattribute = tex.setattribute
+
 do
 
     local shared   = nil
@@ -177,8 +185,9 @@ do
             start     = false,
             stop      = false,
         }
-        rubylist[nofrubies] = setmetatableindex(t, shared)
-        texsetattribute(a_ruby,nofrubies)
+     -- rubylist[nofrubies] = setmetatableindex(t,shared)
+     -- texsetattribute(a_ruby,nofrubies)
+        texsetattribute(a_ruby,registervalue(a_ruby,setmetatableindex(t,shared)))
     end
 
     implement {
@@ -189,51 +198,156 @@ do
 
 end
 
+-- function rubies.check(head)
+--     local current = head
+--     local start   = nil
+--     local stop    = nil
+--     local found   = nil
+--
+--     local function flush(where)
+--         local r = rubylist[found]
+--         if r then
+--             local prev = getprev(start)
+--             local next = getnext(stop)
+--             setprev(start)
+--             setnext(stop)
+--             local h = hpack(start)
+--             if start == head then
+--                 head = h
+--             else
+--                 setlink(prev,h)
+--             end
+--             setlink(h,next)
+--             local bwidth = getwidth(h)
+--             local rwidth = r.width
+--             r.basewidth  = bwidth
+--             r.start      = start
+--             r.stop       = stop
+--             setprop(h,"ruby",found)
+--             if rwidth > bwidth then
+--                 -- ruby is wider
+--                 setwidth(h,rwidth)
+--             end
+--         end
+--     end
+--
+--     while current do
+--         local nx = getnext(current)
+--         local id = getid(current)
+--         if id == glyph_code then
+--             local a  = getattr(current,a_ruby)
+--             if not a then
+--                 if found then
+--                     flush("flush 1")
+--                     found = nil
+--                 end
+--             elseif a == found then
+--                 stop = current
+--             else
+--                 if found then
+--                     flush("flush 2")
+--                 end
+--                 found = a
+--                 start = current
+--                 stop  = current
+--             end
+--             -- go on
+--         elseif id == kern_code and getsubtype(current,fontkern_code) then
+--             -- go on
+--         elseif found and id == disc_code then
+--             -- go on (todo: look into disc)
+--         elseif found then
+--             flush("flush 3")
+--             found = nil
+--         end
+--         current = nx
+--     end
+--
+--     if found then
+--         flush("flush 4")
+--     end
+--     return head, true -- no need for true
+-- end
+
 function rubies.check(head)
-    local current = head
-    local start   = nil
-    local stop    = nil
-    local found   = nil
-
-    local function flush(where)
-        local r = rubylist[found]
-        if r then
-            local prev = getprev(start)
-            local next = getnext(stop)
-            setprev(start)
-            setnext(stop)
-            local h = hpack(start)
-            if start == head then
-                head = h
-            else
-                setlink(prev,h)
-            end
-            setlink(h,next)
-            local bwidth = getwidth(h)
-            local rwidth = r.width
-            r.basewidth  = bwidth
-            r.start      = start
-            r.stop       = stop
-            setprop(h,"ruby",found)
-            if rwidth > bwidth then
-                -- ruby is wider
-                setwidth(h,rwidth)
+    local _, current = findattribute(head,a_ruby)
+    if current then
+
+        local start   = nil
+        local stop    = nil
+        local found   = nil
+
+        local function flush(where)
+--            local r = rubylist[found]
+local r = getvalue(a_ruby,found)
+            if r then
+                -- can be an option
+                while start ~= stop and getid(start) == glue_code do
+                    start = getnext(start)
+                end
+                while stop ~= start and getid(stop) == glue_code do
+                    stop = getprev(stop)
+                end
+                --
+                local prev = getprev(start)
+                local next = getnext(stop)
+                setprev(start)
+                setnext(stop)
+                local h = hpack(start)
+                if start == head then
+                    head = h
+                else
+                    setlink(prev,h)
+                end
+                setlink(h,next)
+                local bwidth = getwidth(h)
+                local rwidth = r.width
+                r.basewidth  = bwidth
+                r.start      = start
+                r.stop       = stop
+                setprop(h,"ruby",found)
+                if rwidth > bwidth then
+                    -- ruby is wider
+                    setwidth(h,rwidth)
+                end
             end
         end
-    end
 
-    while current do
-        local nx = getnext(current)
-        local id = getid(current)
-        if id == glyph_code then
+--         while current do
+--             local nx = getnext(current)
+--             local a  = getattr(current,a_ruby)
+--             if not a then
+--                 if found then
+--                     flush("flush 1")
+--                     found = nil
+--                 end
+--             elseif a == found then
+--                 stop = current
+--             else
+--                 if found then
+--                     flush("flush 2")
+--                 end
+--                 found = a
+--                 start = current
+--                 stop  = current
+--             end
+--             current = nx
+--         end
+
+        -- todo: we can avoid a lookup
+
+        while current do
+            local nx = getnext(current)
             local a  = getattr(current,a_ruby)
             if not a then
                 if found then
                     flush("flush 1")
                     found = nil
                 end
+_, current = findattribute(nx,a_ruby)
             elseif a == found then
                 stop = current
+current = nx
             else
                 if found then
                     flush("flush 2")
@@ -241,30 +355,26 @@ function rubies.check(head)
                 found = a
                 start = current
                 stop  = current
+current = nx
             end
-            -- go on
-        elseif id == kern_code and getsubtype(current,fontkern_code) then
-            -- go on
-        elseif found and id == disc_code then
-            -- go on (todo: look into disc)
-        elseif found then
-            flush("flush 3")
-            found = nil
         end
-        current = nx
+
     end
+
     if found then
         flush("flush 4")
     end
     return head, true -- no need for true
 end
 
+
 local attach
 
 local function whatever(current,list)
     local a = getprop(current,"ruby")
     if a then
-        local ruby    = rubylist[a]
+--         local ruby    = rubylist[a]
+local ruby = getvalue(a_ruby,a)
         local align   = ruby.align   or v_middle
         local stretch = ruby.stretch or v_no
         local hoffset = ruby.hoffset or 0
@@ -358,7 +468,7 @@ local function whatever(current,list)
             setlist(current,text)
         end
         setprop(current,"ruby",false)
-        rubylist[a] = nil
+--         rubylist[a] = nil
     elseif list then
         attach(list)
     end
diff --git a/tex/context/fonts/mkiv/pagella-math.lfg b/tex/context/fonts/mkiv/pagella-math.lfg
index 9be98adcf..021bd2b7f 100644
--- a/tex/context/fonts/mkiv/pagella-math.lfg
+++ b/tex/context/fonts/mkiv/pagella-math.lfg
@@ -261,6 +261,18 @@ return {
                     tweak = "addfourier",
                     variant = 1,
                 },
+
+{
+    tweak = "kernpairs",
+    list = {
+        -- beware: we kept the italic correction in spite of punctuation class
+        [0x1D453] = { -- f
+            [0x3A] = -.1,
+            [0x3B] = -.1,
+        },
+    },
+},
+
             },
         },
         bigslots = {
diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml
index 2ff113ecd..51785d147 100644
--- a/tex/context/interface/mkii/keys-de.xml
+++ b/tex/context/interface/mkii/keys-de.xml
@@ -96,7 +96,6 @@
 		<cd:variable name='author' value='autor'/>
 		<cd:variable name='auto' value='auto'/>
 		<cd:variable name='autointro' value='autointro'/>
-		<cd:variable name='autopunctuation' value='autopunctuation'/>
 		<cd:variable name='back' value='zurueck'/>
 		<cd:variable name='background' value='hintergrund'/>
 		<cd:variable name='backmatter' value='epiloge'/>
@@ -686,6 +685,9 @@
 		<cd:constant name='autofile' value='autofile'/>
 		<cd:constant name='autofocus' value='autofocus'/>
 		<cd:constant name='autohang' value='autohang'/>
+		<cd:constant name='autonumbers' value='autonumbers'/>
+		<cd:constant name='autopunctuation' value='autopunctuation'/>
+		<cd:constant name='autospacing' value='autospacing'/>
 		<cd:constant name='autostrut' value='autostrut'/>
 		<cd:constant name='autowidth' value='autobreite'/>
 		<cd:constant name='availableheight' value='availableheight'/>
@@ -876,6 +878,7 @@
 		<cd:constant name='frameradius' value='rahmenradius'/>
 		<cd:constant name='frames' value='umrahmen'/>
 		<cd:constant name='freeregion' value='freeregion'/>
+		<cd:constant name='freezespacing' value='freezespacing'/>
 		<cd:constant name='from' value='von'/>
 		<cd:constant name='functioncolor' value='functioncolor'/>
 		<cd:constant name='functionstyle' value='functionstyle'/>
@@ -956,6 +959,7 @@
 		<cd:constant name='lastpubsep' value='lastpubsep'/>
 		<cd:constant name='layout' value='layout'/>
 		<cd:constant name='left' value='links'/>
+		<cd:constant name='leftclass' value='leftclass'/>
 		<cd:constant name='leftcolor' value='linkerfarbe'/>
 		<cd:constant name='leftcompoundhyphen' value='leftcompoundhyphen'/>
 		<cd:constant name='leftedge' value='linkekante'/>
@@ -1014,6 +1018,7 @@
 		<cd:constant name='menu' value='menue'/>
 		<cd:constant name='method' value='methode'/>
 		<cd:constant name='middle' value='mittig'/>
+		<cd:constant name='middleclass' value='middleclass'/>
 		<cd:constant name='middlecolor' value='middlecolor'/>
 		<cd:constant name='middlecommand' value='middlecommand'/>
 		<cd:constant name='middlesource' value='middlesource'/>
@@ -1060,6 +1065,8 @@
 		<cd:constant name='numberconversionset' value='numberconversionset'/>
 		<cd:constant name='numberdistance' value='numberdistance'/>
 		<cd:constant name='numbering' value='nummerierung'/>
+		<cd:constant name='numberlocation' value='numberlocation'/>
+		<cd:constant name='numbermethod' value='numbermethod'/>
 		<cd:constant name='numberorder' value='numberorder'/>
 		<cd:constant name='numberprefix' value='numberprefix'/>
 		<cd:constant name='numbersegments' value='numbersegments'/>
@@ -1070,6 +1077,7 @@
 		<cd:constant name='numberstopper' value='numberstopper'/>
 		<cd:constant name='numberstrut' value='numberstrut'/>
 		<cd:constant name='numberstyle' value='nummernstil'/>
+		<cd:constant name='numberthreshold' value='numberthreshold'/>
 		<cd:constant name='numberwidth' value='numberwidth'/>
 		<cd:constant name='nx' value='nx'/>
 		<cd:constant name='ny' value='ny'/>
@@ -1123,6 +1131,7 @@
 		<cd:constant name='palet' value='palette'/>
 		<cd:constant name='paper' value='papier'/>
 		<cd:constant name='paragraph' value='absatz'/>
+		<cd:constant name='penalties' value='penalties'/>
 		<cd:constant name='period' value='period'/>
 		<cd:constant name='place' value='platziere'/>
 		<cd:constant name='placehead' value='setzekopf'/>
@@ -1176,6 +1185,7 @@
 		<cd:constant name='reverse' value='reverse'/>
 		<cd:constant name='right' value='rechts'/>
 		<cd:constant name='rightchars' value='rightchars'/>
+		<cd:constant name='rightclass' value='rightclass'/>
 		<cd:constant name='rightcolor' value='rechterfarbe'/>
 		<cd:constant name='rightcompoundhyphen' value='rightcompoundhyphen'/>
 		<cd:constant name='rightedge' value='rechtekante'/>
diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml
index eedcdaa82..08686da99 100644
--- a/tex/context/interface/mkii/keys-it.xml
+++ b/tex/context/interface/mkii/keys-it.xml
@@ -96,7 +96,6 @@
 		<cd:variable name='author' value='autore'/>
 		<cd:variable name='auto' value='auto'/>
 		<cd:variable name='autointro' value='autointro'/>
-		<cd:variable name='autopunctuation' value='autopunctuation'/>
 		<cd:variable name='back' value='dietro'/>
 		<cd:variable name='background' value='sfondo'/>
 		<cd:variable name='backmatter' value='postambolo'/>
@@ -686,6 +685,9 @@
 		<cd:constant name='autofile' value='autofile'/>
 		<cd:constant name='autofocus' value='autofocus'/>
 		<cd:constant name='autohang' value='autohang'/>
+		<cd:constant name='autonumbers' value='autonumbers'/>
+		<cd:constant name='autopunctuation' value='autopunctuation'/>
+		<cd:constant name='autospacing' value='autospacing'/>
 		<cd:constant name='autostrut' value='autostrut'/>
 		<cd:constant name='autowidth' value='autoampiezza'/>
 		<cd:constant name='availableheight' value='availableheight'/>
diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml
index 78255c1cc..360ec0f64 100644
--- a/tex/context/interface/mkii/keys-ro.xml
+++ b/tex/context/interface/mkii/keys-ro.xml
@@ -96,7 +96,6 @@
 		<cd:variable name='author' value='autor'/>
 		<cd:variable name='auto' value='auto'/>
 		<cd:variable name='autointro' value='autointro'/>
-		<cd:variable name='autopunctuation' value='autopunctuation'/>
 		<cd:variable name='back' value='inapot'/>
 		<cd:variable name='background' value='fundal'/>
 		<cd:variable name='backmatter' value='epilogul'/>
@@ -686,6 +685,9 @@
 		<cd:constant name='autofile' value='autofile'/>
 		<cd:constant name='autofocus' value='autofocus'/>
 		<cd:constant name='autohang' value='autohang'/>
+		<cd:constant name='autonumbers' value='autonumbers'/>
+		<cd:constant name='autopunctuation' value='autopunctuation'/>
+		<cd:constant name='autospacing' value='autospacing'/>
 		<cd:constant name='autostrut' value='autostrut'/>
 		<cd:constant name='autowidth' value='autolatime'/>
 		<cd:constant name='availableheight' value='availableheight'/>
diff --git a/tex/context/modules/mkiv/s-abbreviations-logos.tex b/tex/context/modules/mkiv/s-abbreviations-logos.tex
index dfac57f0a..ab2b98a56 100644
--- a/tex/context/modules/mkiv/s-abbreviations-logos.tex
+++ b/tex/context/modules/mkiv/s-abbreviations-logos.tex
@@ -42,6 +42,7 @@
 \logo [ANSI]          {ansi}
 \logo [APA]           {apa}
 \logo [API]           {api}
+\logo [APL]           {apl}
 \logo [ARABTEX]       {Arab\TeXsuffix}
 \logo [ARM]           {arm}
 \logo [ASCII]         {ascii}
diff --git a/tex/context/modules/mkxl/m-gimmicks.mkxl b/tex/context/modules/mkxl/m-gimmicks.mkxl
index e2659ae99..bdf044488 100644
--- a/tex/context/modules/mkxl/m-gimmicks.mkxl
+++ b/tex/context/modules/mkxl/m-gimmicks.mkxl
@@ -1,6 +1,6 @@
 %D \module
 %D   [       file=m-gimmicks,
-%D        version=2022.07.25
+%D        version=2022.08.25
 %D          title=\CONTEXT\ Extra Modules,
 %D       subtitle=Whatever comes up,
 %D         author=Hans Hagen,
@@ -41,13 +41,13 @@
 
 % Question on mailing list:
 
-\chardef\MacAnulty = \getprivateglyphslot{MacAnulty}
+\chardef\MacAnulty = \privatecharactercode{MacAnulty}
 
-\startsetups [box:demo:\number\MacAnulty]
+\startsetups [box:mcanulty:\number\MacAnulty]
     \Mac Anulty
 \stopsetups
 
-\registerboxglyph category {demo} unicode \MacAnulty \relax
+\registerboxglyph category {mcanulty} unicode \MacAnulty \relax
 
 \startluacode
     fonts.handlers.otf.addfeature {
@@ -55,13 +55,17 @@
         type    = "ligature",
         nocheck = true,
         data    = {
-         -- [\number\MacAnulty]                         = { "M", "c", "A", "n", "u", "l", "t", "y", },
-            [fonts.constructors.privateslots.MacAnulty] = { "M", "c", "A", "n", "u", "l", "t", "y", },
+         -- [\number\MacAnulty]                         = {
+         -- [fonts.constructors.privateslots.MacAnulty] = {
+            [fonts.helpers.privateslot("MacAnulty")]    = {
+                "M", "c", "A", "n", "u", "l", "t", "y",
+            },
         }
     }
 \stopluacode
 
-\definefontfeature[whatever][default][box=demo,mcanulty=yes]
+\definefontfeature[whatever][default][box=mcanulty,mcanulty=yes]
+\definefontfeature[default][default][box=mcanulty,mcanulty=yes]
 
 \startTEXpage [offset=10dk]
 %     \def\Test#1{%
@@ -83,7 +87,10 @@
 %     \def\MacKern {-.1}
 %     \Mac Anulty
 
-\definedfont[Serif*whatever]     McAnulty\quad \MacAnulty\par
-\definedfont[SerifBold*whatever] McAnulty\quad \MacAnulty\par
+{\definedfont[Serif*whatever]     McAnulty\quad \MacAnulty\par}
+{\definedfont[SerifBold*whatever] McAnulty\quad \MacAnulty\par}
+
+{\tf McAnulty\quad \MacAnulty\par}
+{\bf McAnulty\quad \MacAnulty\par}
 
 \stopTEXpage
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 0c0f32e66..1b464f549 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  : 2022-08-25 19:18
+-- merge date  : 2022-09-10 02:42
 
 do -- begin closure to overcome local limits and interference
 
-- 
cgit v1.2.3