From ca2f0f64dbb46140d36db84ac6e1b6079a386cfa Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Tue, 2 Nov 2021 10:26:54 +0100
Subject: 2021-11-02 10:02:00

---
 tex/context/base/mkii/cont-new.mkii                |   2 +-
 tex/context/base/mkii/context.mkii                 |   2 +-
 tex/context/base/mkii/mult-en.mkii                 |   2 +
 tex/context/base/mkii/mult-ro.mkii                 |   2 +
 tex/context/base/mkiv/cont-new.mkiv                |   2 +-
 tex/context/base/mkiv/context.mkiv                 |   2 +-
 tex/context/base/mkiv/mult-def.lua                 |  20 ++
 tex/context/base/mkiv/mult-prm.lua                 |   4 +
 tex/context/base/mkiv/status-files.pdf             | Bin 24701 -> 24767 bytes
 tex/context/base/mkiv/status-lua.pdf               | Bin 253854 -> 253917 bytes
 tex/context/base/mkiv/syst-aux.mkiv                |  23 +-
 tex/context/base/mkiv/trac-deb.lua                 |   6 +-
 tex/context/base/mkxl/cont-new.mkxl                |   2 +-
 tex/context/base/mkxl/context.mkxl                 |   2 +-
 tex/context/base/mkxl/driv-shp.lmt                 | 260 ++++++++++---------
 tex/context/base/mkxl/font-imp-math.lmt            |   5 +-
 tex/context/base/mkxl/lpdf-lmt.lmt                 |  60 +++--
 tex/context/base/mkxl/node-tsk.lmt                 |  19 +-
 tex/context/base/mkxl/page-app.mkxl                |   1 +
 tex/context/base/mkxl/tabl-frm.mkxl                |   3 +-
 tex/context/base/mkxl/trac-deb.lmt                 |   6 +-
 tex/context/base/mkxl/typo-lbx.lmt                 | 237 ++++++++++-------
 tex/context/base/mkxl/typo-lbx.mkxl                | 279 ++++++++++++++++-----
 tex/context/fonts/mkiv/ebgaramond.lfg              |  38 +++
 tex/context/fonts/mkiv/libertinus-math.lfg         | 110 +++++---
 tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv    |  24 +-
 tex/context/interface/mkii/keys-en.xml             |   2 +
 tex/context/interface/mkii/keys-ro.xml             |   2 +
 tex/generic/context/luatex/luatex-fonts-merged.lua |   2 +-
 29 files changed, 749 insertions(+), 368 deletions(-)

(limited to 'tex')

diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 3fac13aaf..2ac02f2e3 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{2021.10.28 10:17}
+\newcontextversion{2021.11.02 09:59}
 
 %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 fedf5acb3..5bf011408 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{2021.10.28 10:17}
+\edef\contextversion{2021.11.02 09:59}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii
index f990c83e5..fcf27a17b 100644
--- a/tex/context/base/mkii/mult-en.mkii
+++ b/tex/context/base/mkii/mult-en.mkii
@@ -315,6 +315,7 @@
 \setinterfacevariable{lefthanging}{lefthanging}
 \setinterfacevariable{leftmargin}{leftmargin}
 \setinterfacevariable{leftpage}{leftpage}
+\setinterfacevariable{lefttext}{lefttext}
 \setinterfacevariable{lefttoright}{lefttoright}
 \setinterfacevariable{legend}{legend}
 \setinterfacevariable{less}{less}
@@ -476,6 +477,7 @@
 \setinterfacevariable{righthanging}{righthanging}
 \setinterfacevariable{rightmargin}{rightmargin}
 \setinterfacevariable{rightpage}{rightpage}
+\setinterfacevariable{righttext}{righttext}
 \setinterfacevariable{righttoleft}{righttoleft}
 \setinterfacevariable{roman}{roman}
 \setinterfacevariable{romannumerals}{romannumerals}
diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii
index 87a4a91c0..5db4797e4 100644
--- a/tex/context/base/mkii/mult-ro.mkii
+++ b/tex/context/base/mkii/mult-ro.mkii
@@ -315,6 +315,7 @@
 \setinterfacevariable{lefthanging}{lefthanging}
 \setinterfacevariable{leftmargin}{marginestanga}
 \setinterfacevariable{leftpage}{paginastanga}
+\setinterfacevariable{lefttext}{textstanga}
 \setinterfacevariable{lefttoright}{lefttoright}
 \setinterfacevariable{legend}{legenda}
 \setinterfacevariable{less}{less}
@@ -476,6 +477,7 @@
 \setinterfacevariable{righthanging}{righthanging}
 \setinterfacevariable{rightmargin}{marginedreapta}
 \setinterfacevariable{rightpage}{paginadreapta}
+\setinterfacevariable{righttext}{textdreapta}
 \setinterfacevariable{righttoleft}{righttoleft}
 \setinterfacevariable{roman}{roman}
 \setinterfacevariable{romannumerals}{numereromane}
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 8c12216dd..5bee9fbb3 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{2021.10.28 10:17}
+\newcontextversion{2021.11.02 09:59}
 
 %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 6cc906cf4..c61fb2936 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{2021.10.28 10:17}
+\edef\contextversion{2021.11.02 09:59}
 
 %D Kind of special:
 
diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua
index 7c62df864..2cc8a1c19 100644
--- a/tex/context/base/mkiv/mult-def.lua
+++ b/tex/context/base/mkiv/mult-def.lua
@@ -16590,6 +16590,16 @@ return {
    ["pe"]="حاشیه‌چپ",
    ["ro"]="marginestanga",
   },
+  ["lefttext"]={
+   ["cs"]="textvlevo",
+   ["de"]="linkertext",
+   ["en"]="lefttext",
+   ["fr"]="textegauche",
+   ["it"]="testosinistro",
+   ["nl"]="linkertekst",
+   ["pe"]="متن‌چپ",
+   ["ro"]="textstanga",
+  },
   ["leftpage"]={
    ["cs"]="levastranka",
    ["de"]="linkerseite",
@@ -18040,6 +18050,16 @@ return {
    ["pe"]="صفحه‌راست",
    ["ro"]="paginadreapta",
   },
+  ["righttext"]={
+   ["cs"]="textvpravo",
+   ["de"]="rechtertext",
+   ["en"]="righttext",
+   ["fr"]="textedroite",
+   ["it"]="testodestro",
+   ["nl"]="rechtertekst",
+   ["pe"]="متن‌راست",
+   ["ro"]="textdreapta",
+  },
   ["righttoleft"]={
    ["cs"]="righttoleft",
    ["de"]="righttoleft",
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index d0312e18d..7579eb4e9 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -428,7 +428,10 @@ return {
   "localcontrolled",
   "localinterlinepenalty",
   "localleftbox",
+  "localleftboxbox",
+  "localmiddlebox",
   "localrightbox",
+  "localrightboxbox",
   "lpcode",
   "luabytecode",
   "luabytecodecall",
@@ -520,6 +523,7 @@ return {
   "tracingalignments",
   "tracingexpressions",
   "tracingfonts",
+  "tracingfullboxes",
   "tracinghyphenation",
   "tracinginserts",
   "tracingmarks",
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 4a0bc353d..6e149394e 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 78253afaf..ed087bd8f 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/syst-aux.mkiv b/tex/context/base/mkiv/syst-aux.mkiv
index 194f1de2c..79b118a9b 100644
--- a/tex/context/base/mkiv/syst-aux.mkiv
+++ b/tex/context/base/mkiv/syst-aux.mkiv
@@ -1470,10 +1470,20 @@
 
 % replaces prev
 
+% \protected\def\syst_helpers_do_if_in_string_else#1#2% ##2 can be {abc}
+%   {\expandafter\def\expandafter\syst_helpers_do_do_if_in_string_else
+%      \expandafter##\expandafter1#1##2##3^^^^0004{\unless\if##2@}% expand #1 here
+%    \expandafter\syst_helpers_do_do_if_in_string_else\normalexpanded{#2#1}@@^^^^0004} % expand #2 here
+
 \protected\def\syst_helpers_do_if_in_string_else#1#2% ##2 can be {abc}
   {\expandafter\def\expandafter\syst_helpers_do_do_if_in_string_else
-     \expandafter##\expandafter1#1##2##3^^^^0004{\unless\if##2@}% expand #1 here
-   \expandafter\syst_helpers_do_do_if_in_string_else\normalexpanded{#2#1}@@^^^^0004} % expand #2 here
+     \expandafter##\expandafter1#1##2##3^^^^0004{\unless\ifx##2^^^^0003}% expand #1 here
+   \expandafter\syst_helpers_do_do_if_in_string_else\normalexpanded{#2#1}^^^^0003^^^^0003^^^^0004} % expand #2 here
+
+% \protected\def\syst_helpers_do_if_in_string_else#1#2% ##2 can be {abc}
+%   {\normalexpanded{\def\noexpand\syst_helpers_do_do_if_in_string_else
+%      ##1#1##2##3}^^^^0004{\unless\ifx##2^^^^0003}% expand #1 here
+%    \normalexpanded{\noexpand\syst_helpers_do_do_if_in_string_else#2#1}^^^^0003^^^^0003^^^^0004} % expand #2 here
 
 %D The next alternative proved to be upto twice as fast on tasks like checking
 %D reserved words in pretty verbatim typesetting! This is mainly due to the fact
@@ -1486,10 +1496,15 @@
 %D Where \type {\doifinstringelse} does as much expansion as possible, the latter
 %D alternative does minimal (one level) expansion.
 
+% \protected\def\syst_helpers_do_if_in_csname_else#1#2%
+%   {\def\syst_helpers_do_do_if_in_csname_else##1#1##2##3^^^^0004%
+%      {\unless\if##2@}%
+%    \expandafter\syst_helpers_do_do_if_in_csname_else#2#1@@^^^^0004}
+
 \protected\def\syst_helpers_do_if_in_csname_else#1#2%
   {\def\syst_helpers_do_do_if_in_csname_else##1#1##2##3^^^^0004%
-     {\unless\if##2@}%
-   \expandafter\syst_helpers_do_do_if_in_csname_else#2#1@@^^^^0004}
+     {\unless\ifx##2^^^^3}%
+   \expandafter\syst_helpers_do_do_if_in_csname_else#2#1^^^^3^^^^3^^^^0004}
 
 \protected\def\doifelseincsname#1#2%
   {\normalexpanded{\syst_helpers_do_if_in_csname_else{#1}}{#2}%
diff --git a/tex/context/base/mkiv/trac-deb.lua b/tex/context/base/mkiv/trac-deb.lua
index 07865e4bf..88d7e54c6 100644
--- a/tex/context/base/mkiv/trac-deb.lua
+++ b/tex/context/base/mkiv/trac-deb.lua
@@ -191,9 +191,11 @@ function tracers.printerror(specification)
             report_str(tracers.showlines(filename,linenumber,offset,tonumber(luaerrorline)))
             report_nl()
         end
-        local errname = file.addsuffix(tex.jobname .. "-error","log")
         if quitonerror then
-            table.save(errname,specification)
+            local name = tex.jobname or ""
+            if name ~= "" then
+                table.save(name .. "-error.log",specification)
+            end
             local help = specification.lasttexhelp
             if help and #help > 0 then
                 report_nl()
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index c09d7a8ae..9f20ffaf8 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{2021.10.28 10:17}
+\newcontextversion{2021.11.02 09:59}
 
 %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 afb958933..f48c343c5 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{2021.10.28 10:17}
+\immutable\edef\contextversion{2021.11.02 09:59}
 
 %overloadmode 1 % check frozen / warning
 %overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt
index a917d9501..f24a4090f 100644
--- a/tex/context/base/mkxl/driv-shp.lmt
+++ b/tex/context/base/mkxl/driv-shp.lmt
@@ -9,87 +9,89 @@ if not modules then modules = { } end modules ['driv-shp'] = {
 
 local type, next = type, next
 
-local setmetatableindex = table.setmetatableindex
-local formatters        = string.formatters
-local concat            = table.concat
-local keys              = table.keys
-local sortedhash        = table.sortedhash
-local find              = string.find
-local stripstring       = string.strip
-local sequenced         = table.sequenced
-local round             = math.round
-local nuts              = nodes.nuts
-
-local tonut             = nodes.tonut
-local tonode            = nodes.tonode
-
-local getdirection      = nuts.getdirection
-local getlist           = nuts.getlist
-local getoffsets        = nuts.getoffsets
-local getorientation    = nuts.getorientation
-local getwhd            = nuts.getwhd
-local getkern           = nuts.getkern
-local getheight         = nuts.getheight
-local getdepth          = nuts.getdepth
------ getwidth          = nuts.getwidth
-local getnext           = nuts.getnext
-local getsubtype        = nuts.getsubtype
-local getid             = nuts.getid
-local getleader         = nuts.getleader
------ getglue           = nuts.getglue
-local getshift          = nuts.getshift
-local getreplace        = nuts.getreplace
-local setreplace        = nuts.setreplace
-local getfont           = nuts.getfont
-local getkerndimension  = nuts.getkerndimension
-
-local setdirection      = nuts.setdirection
-local setlink           = nuts.setlink
-
-local isglyph           = nuts.isglyph
------ nextdir           = nuts.traversers.dir
-local nextnode          = nuts.traversers.node
-
-local effectiveglue     = nuts.effectiveglue
-local dirdimensions     = nuts.dirdimensions
-
-local fonthashes        = fonts.hashes
-local fontdata          = fonthashes.identifiers
-local characters        = fonthashes.characters
-local parameters        = fonthashes.parameters
-
-local nodecodes         = nodes.nodecodes
-local whatsitcodes      = nodes.whatsitcodes
-local gluecodes         = nodes.gluecodes
-local dirvalues         = nodes.dirvalues
-local subtypes          = nodes.subtypes
-
-local lefttoright_code  = dirvalues.lefttoright
-local righttoleft_code  = dirvalues.righttoleft
-
-local glyph_code        = nodecodes.glyph
-local kern_code         = nodecodes.kern
-local glue_code         = nodecodes.glue
-local hlist_code        = nodecodes.hlist
-local vlist_code        = nodecodes.vlist
-local dir_code          = nodecodes.dir
-local disc_code         = nodecodes.disc
-local math_code         = nodecodes.math
-local rule_code         = nodecodes.rule
-local whatsit_code      = nodecodes.whatsit
-
-local leaders_code      = gluecodes.leaders
-local cleaders_code     = gluecodes.cleaders
-local xleaders_code     = gluecodes.xleaders
-local gleaders_code     = gluecodes.gleaders
-
-local spaceskip_code    = gluecodes.spaceskip
-
-local getpagedimensions = layouts.getpagedimensions
-
-local drivers           = drivers
-
-local report            = logs.reporter("drivers")
+local setmetatableindex  = table.setmetatableindex
+local formatters         = string.formatters
+local concat             = table.concat
+local keys               = table.keys
+local sortedhash         = table.sortedhash
+local find               = string.find
+local stripstring        = string.strip
+local sequenced          = table.sequenced
+local round              = math.round
+local nuts               = nodes.nuts
+
+local tonut              = nodes.tonut
+local tonode             = nodes.tonode
+
+local getdirection       = nuts.getdirection
+local getlist            = nuts.getlist
+local getoffsets         = nuts.getoffsets
+local getorientation     = nuts.getorientation
+local getxyscales        = nuts.getxyscales
+local getwhd             = nuts.getwhd
+local getkern            = nuts.getkern
+local getheight          = nuts.getheight
+local getdepth           = nuts.getdepth
+----- getwidth           = nuts.getwidth
+local getnext            = nuts.getnext
+local getsubtype         = nuts.getsubtype
+local getid              = nuts.getid
+local getleader          = nuts.getleader
+----- getglue            = nuts.getglue
+local getshift           = nuts.getshift
+local getreplace         = nuts.getreplace
+local setreplace         = nuts.setreplace
+local getfont            = nuts.getfont
+local getkerndimension   = nuts.getkerndimension
+local getglyphdimensions = nuts.getglyphdimensions
+
+local setdirection       = nuts.setdirection
+local setlink            = nuts.setlink
+
+local isglyph            = nuts.isglyph
+----- nextdir            = nuts.traversers.dir
+local nextnode           = nuts.traversers.node
+
+local effectiveglue      = nuts.effectiveglue
+local dirdimensions      = nuts.dirdimensions
+
+local fonthashes         = fonts.hashes
+local fontdata           = fonthashes.identifiers
+local characters         = fonthashes.characters
+local parameters         = fonthashes.parameters
+
+local nodecodes          = nodes.nodecodes
+local whatsitcodes       = nodes.whatsitcodes
+local gluecodes          = nodes.gluecodes
+local dirvalues          = nodes.dirvalues
+local subtypes           = nodes.subtypes
+
+local lefttoright_code   = dirvalues.lefttoright
+local righttoleft_code   = dirvalues.righttoleft
+
+local glyph_code         = nodecodes.glyph
+local kern_code          = nodecodes.kern
+local glue_code          = nodecodes.glue
+local hlist_code         = nodecodes.hlist
+local vlist_code         = nodecodes.vlist
+local dir_code           = nodecodes.dir
+local disc_code          = nodecodes.disc
+local math_code          = nodecodes.math
+local rule_code          = nodecodes.rule
+local whatsit_code       = nodecodes.whatsit
+
+local leaders_code       = gluecodes.leaders
+local cleaders_code      = gluecodes.cleaders
+local xleaders_code      = gluecodes.xleaders
+local gleaders_code      = gluecodes.gleaders
+
+local spaceskip_code     = gluecodes.spaceskip
+
+local getpagedimensions  = layouts.getpagedimensions
+
+local drivers            = drivers
+
+local report             = logs.reporter("drivers")
 
 ---------------------------------------------------------------------------------------
 
@@ -291,7 +293,7 @@ local flush_character do
                     pos_v = pos_v + v * sy
                 end
                 if c then
-                    flushchar(fnt,c)
+                    flushchar(fnt,c) -- todo: e f !
                     pos_h = ph
                     pos_v = pv
                 end
@@ -466,8 +468,6 @@ local flush_character do
 
     local onetimemessage -- could be defined later (todo: make plug for this)
 
-    local getxyscales = nuts.getxyscales
-
     flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r,f,e)
 
         if font ~= lastfont then
@@ -492,14 +492,19 @@ local flush_character do
         end
         local width, height, depth, naturalwidth, sx, sy
         if current then
-            naturalwidth, height, depth, factor = getwhd(current,true) -- also get corrected width
-            sx, sy = getxyscales(current) -- maybe: getwhdfs
-            if factor == 0 then
-                width = naturalwidth
+            -- height and depth not needed
+            if true then
+                width, height, depth, factor, sx, sy = getglyphdimensions(current)
             else
-             -- width = (1.0 + factor/1000000.0) * naturalwidth
-                width = naturalwidth + naturalwidth * factor/1000000.0
-             -- width = naturalwidth + naturalwidth * 0.000001 * factor
+                naturalwidth, height, depth, factor = getwhd(current,true) -- also get corrected width
+                sx, sy = getxyscales(current)
+                if factor == 0 then
+                    width = naturalwidth
+                else
+                 -- width = (1.0 + factor/1000000.0) * naturalwidth
+                    width = naturalwidth + naturalwidth * factor/1000000.0
+                 -- width = naturalwidth + naturalwidth * 0.000001 * factor
+                end
             end
         else
             width  = data.width or 0
@@ -537,7 +542,6 @@ local flush_character do
                 flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor,sx,sy) -- ,naturalwidth,width)
             end
         end
-
         return width, height, depth
     end
 
@@ -627,28 +631,6 @@ local hlist_out, vlist_out  do
 
     -- to be checked: begin- or enddir kan nil zijn, weird
 
- -- local function calculate_width_to_enddir(this_box,begindir) -- can be a helper
- --     local dir_nest = 1
- --     local enddir   = begindir
- --     for current, subtype in nextdir, getnext(begindir) do
- --         if subtype == normaldir_code then -- todo
- --             dir_nest = dir_nest + 1
- --         else
- --             dir_nest = dir_nest - 1
- --         end
- --         if dir_nest == 0 then -- does the type matter
- --             enddir = current
- --             local width = rangedimensions(this_box,begindir,enddir)
- --             return enddir, width
- --         end
- --     end
- --     if enddir == begindir then
- --         local width = rangedimensions(this_box,begindir) -- ,enddir)
- --         return enddir, width
- --     end
- --     return enddir, 0
- -- end
-
     -- check frequencies of nodes
 
     hlist_out = function(this_box,current)
@@ -686,8 +668,8 @@ local hlist_out, vlist_out  do
                 pos_v = pos_v + raise
                 pos_h = pos_h - left
                 local wd = flush_character(current,font,char,false,true,pos_h,pos_v,pos_r)
---                 cur_h = cur_h + wd - right -- hm, no left here?
-cur_h = cur_h + wd -- see new tabulate alignment code
+             -- cur_h = cur_h + wd - right -- hm, no left here?
+                cur_h = cur_h + wd -- see new tabulate alignment code
             elseif id == glue_code then
                 local gluewidth = effectiveglue(current,this_box)
                 if gluewidth ~= 0 then
@@ -781,8 +763,8 @@ cur_h = cur_h + wd -- see new tabulate alignment code
                         end
                     else
                         if tospace and subtype == spaceskip_code then
-                            -- todo: flush_space
-                            flush_character(false,getfont(current),32,false,true,pos_h,pos_v,pos_r) -- we need tp pass current for scale?
+                         -- kind of tricky because because we can have a different sx sy
+                            flush_character(false,getfont(current),32,false,true,pos_h,pos_v,pos_r) -- we need to pass current for scale?
                         end
                         cur_h = cur_h + gluewidth
                     end
@@ -861,15 +843,21 @@ cur_h = cur_h + wd -- see new tabulate alignment code
                 end
                 cur_h = cur_h + width
             elseif id == kern_code then
-                -- we can use getkerndimension(current) but then we get rounded values so for
-                -- now we calculate ourselves
-                local kern, factor = getkern(current,true)
-                if kern ~= 0 then
-                    if factor ~= 0 then
-                        cur_h = cur_h + (1.0 + factor/1000000.0) * kern
-                    else
+                -- when we use getkerndimension we get rounded values
+                if true then
+                    local kern = getkerndimension(current)
+                    if kern ~= 0 then
                         cur_h = cur_h + kern
                     end
+                else
+                   local kern, factor = getkern(current,true)
+                   if kern ~= 0 then
+                       if factor ~= 0 then
+                           cur_h = cur_h + (1.0 + factor/1000000.0) * kern
+                       else
+                           cur_h = cur_h + kern
+                       end
+                   end
                 end
             elseif id == rule_code then
                 local width, height, depth = getwhd(current)
@@ -1412,3 +1400,25 @@ do
     end)
 
 end
+
+-- local function calculate_width_to_enddir(this_box,begindir) -- can be a helper
+--     local dir_nest = 1
+--     local enddir   = begindir
+--     for current, subtype in nextdir, getnext(begindir) do
+--         if subtype == normaldir_code then -- todo
+--             dir_nest = dir_nest + 1
+--         else
+--             dir_nest = dir_nest - 1
+--         end
+--         if dir_nest == 0 then -- does the type matter
+--             enddir = current
+--             local width = rangedimensions(this_box,begindir,enddir)
+--             return enddir, width
+--         end
+--     end
+--     if enddir == begindir then
+--         local width = rangedimensions(this_box,begindir) -- ,enddir)
+--         return enddir, width
+--     end
+--     return enddir, 0
+-- end
diff --git a/tex/context/base/mkxl/font-imp-math.lmt b/tex/context/base/mkxl/font-imp-math.lmt
index bf3c8b56e..3077d0dcd 100644
--- a/tex/context/base/mkxl/font-imp-math.lmt
+++ b/tex/context/base/mkxl/font-imp-math.lmt
@@ -101,13 +101,13 @@ function fonts.helpers.mathscriptslots(tfmdata,textcode)
 end
 
 local function manipulate(tfmdata,value)
-    if texconditionals["c_font_compact"] then
+ -- if texconditionals["c_font_compact"] then
+    if value then -- so basically always
         local rawdata           = tfmdata.shared.rawdata
         local rawresources      = rawdata and rawdata.resources
         local rawfeatures       = rawresources and rawresources.features
         local basesubstitutions = rawfeatures and rawfeatures.gsub
         local sequences         = basesubstitutions and tfmdata.resources.sequences
-
         if sequences then
             local characters = tfmdata.characters
             for s=1,#sequences do
@@ -153,6 +153,7 @@ local function manipulate(tfmdata,value)
 end
 
 local function initialize(tfmdata,value)
+    -- Here it really gets enabled as the scales are used.
     if texconditionals["c_font_compact"] then
         local rawdata       = tfmdata.shared.rawdata
         local rawresources  = rawdata and rawdata.resources
diff --git a/tex/context/base/mkxl/lpdf-lmt.lmt b/tex/context/base/mkxl/lpdf-lmt.lmt
index f6cf9f072..81df491c2 100644
--- a/tex/context/base/mkxl/lpdf-lmt.lmt
+++ b/tex/context/base/mkxl/lpdf-lmt.lmt
@@ -186,7 +186,7 @@ end
 -- fonts
 
 local fontcharacters
-local fontdescriptions
+----- fontdescriptions
 local fontparameters
 local fontproperties
 local pdfcharacters
@@ -237,7 +237,7 @@ local tjfactor       = 100 / 65536
 
 function flushers.updatefontstate(font)
     fontcharacters   = characters[font]
-    fontdescriptions = descriptions[font]
+ -- fontdescriptions = descriptions[font]
     fontparameters   = parameters[font]
     fontproperties   = properties[font]
     local size       = fontparameters.size -- or bad news
@@ -468,23 +468,55 @@ do
 
     -- when changing this, check math: compact-001.tex (rule width)
 
+--     local naturalwidths = setmetatableindex(function(t,font)
+--         local d = descriptions[font]
+--         local c = characters[font]
+--         local f = parameters[font].hfactor or parameters[font].factor
+--         local v = setmetatableindex(function(t,char)
+--             local w
+--             local e = c and c[char]
+--             if e then
+--                 w = e.width or 0
+--             end
+--             if not w then
+--                 e = d and d[char]
+--                 if e then
+--                     w = e.width
+--                     if w then
+--                         w =  w * f
+--                     end
+--                 end
+--             end
+--             if not w then
+--                 w = 0
+--             end
+--             t[char] = w
+--             return w
+--         end)
+--         t[font] = v
+--         return v
+--     end)
+
+    -- we need to use descriptions ... otherwise we get wrong dimensions when we use
+    -- characters[n].xoffset or virtual stuff
+
     local naturalwidths = setmetatableindex(function(t,font)
         local d = descriptions[font]
         local c = characters[font]
         local f = parameters[font].hfactor or parameters[font].factor
         local v = setmetatableindex(function(t,char)
             local w
-            local e = c and c[char]
+            local e = d and d[char]
             if e then
-                w = e.width or 0
+                w = e.width
+                if w then
+                    w =  w * f
+                end
             end
             if not w then
-                e = d and d[char]
+                e = c and c[char]
                 if e then
-                    w = e.width
-                    if w then
-                        w =  w * f
-                    end
+                    w = e.width or 0
                 end
             end
             if not w then
@@ -611,7 +643,7 @@ do
         return v
     end)
 
- -- local trace_threshold = false  trackers.register("backends.pdf.threshold", function(v) trace_threshold = v end)
+    local trace_threshold = false  trackers.register("backends.pdf.threshold", function(v) trace_threshold = v end)
 
  -- local f_skip = formatters["%.2N"]
 
@@ -624,16 +656,15 @@ do
             pdf_goto_textmode()
             setup_fontparameters(font,factor,f,e,sx,sy)
             set_font()
-        elseif cur_f ~= f then -- when ok move up
+        elseif cur_f ~= f then -- when ok move up (maybe no longer needed)
             pdf_goto_textmode()
             setup_fontparameters(font,factor,f,e,sx,sy)
             set_font()
---         elseif cur_tmrx ~= tmrx or cur_factor ~= factor or cur_f ~= f or cur_e ~= e then
+     -- elseif cur_tmrx ~= tmrx or cur_factor ~= factor or cur_f ~= f or cur_e ~= e then
         elseif cur_tmrx ~= tmrx or cur_factor ~= factor or cur_e ~= e then
             setup_fontparameters(font,factor,f,e,sx,sy)
             need_tm = true
         end
-
         local move = calc_pdfpos(pos_h,pos_v)
 
         if trace_threshold then
@@ -691,7 +722,6 @@ do
         if mode == "chararray" then
             begin_charmode()
         end
-
         cw = cw + naturalwidth[char] * tmef * f_x_scale
 
         local slot = pdfcharacters[data.index or char] -- registers usage
@@ -2174,7 +2204,6 @@ do
             objnum        = objnum,
             immediate     = true,
             nolength      = nolength,
---             compresslevel = compressed == false and 0 or nil,
             compresslevel = compressed,
             type          = "stream",
             string        = data,
@@ -2190,7 +2219,6 @@ do
         return pdfdeferredobject {
             objnum        = objnum,
             immediate     = true,
---             compresslevel = compressed == false and 0 or nil,
             compresslevel = compressed,
             type          = "stream",
             file          = filename,
diff --git a/tex/context/base/mkxl/node-tsk.lmt b/tex/context/base/mkxl/node-tsk.lmt
index c12c9597e..dfa1e9475 100644
--- a/tex/context/base/mkxl/node-tsk.lmt
+++ b/tex/context/base/mkxl/node-tsk.lmt
@@ -976,30 +976,31 @@ local tonode = nodes.nuts.tonode
 
 %localize%
 
--- line,leftbox,rightbox,linenumber,leftskip,rightskip,lefthang,righthang,indent,parfillleftskip,parfillrightskip
+-- line,leftbox,rightbox,middlebox,linenumber,leftskip,rightskip,lefthang,righthang,indent,parfillleftskip,parfillrightskip
 
-return function(line,leftbox,rightbox,...)
-    nutline     = tonut(line)
-    nutleftbox  = leftbox  and tonut(leftbox)
-    nutrightbox = rightbox and tonut(rightbox)
+return function(line,leftbox,rightbox,middlebox,...)
+    nutline      = tonut(line)
+    nutleftbox   = leftbox  and tonut(leftbox)
+    nutrightbox  = rightbox and tonut(rightbox)
+    nutmiddlebox = middlebox and tonut(middlebox)
 %actions%
 end
 ]],
 
 step = [[
-    tonut((%action%(line,leftbox,rightbox,...)))
+    tonut((%action%(line,leftbox,rightbox,middlebox,...)))
 ]],
 
 nut  = [[
-    %action%(nutline,nutleftbox,nutrightbox,...)
+    %action%(nutline,nutleftbox,nutrightbox,nutmiddlebox,...)
 ]],
 
 nohead = [[
-    %action%(line,leftbox,rightbox,...)
+    %action%(line,leftbox,rightbox,middlebox,...)
 ]],
 
 nonut = [[
-    %action%(nutline,nutleftbox,nutrightbox,...)
+    %action%(nutline,nutleftbox,nutrightbox,nutmiddlebox,...)
 ]],
 
     }
diff --git a/tex/context/base/mkxl/page-app.mkxl b/tex/context/base/mkxl/page-app.mkxl
index d41487640..67699143a 100644
--- a/tex/context/base/mkxl/page-app.mkxl
+++ b/tex/context/base/mkxl/page-app.mkxl
@@ -75,6 +75,7 @@
       \bgroup
       \inheritedfittingpageframed
       \bgroup
+      \pack_framed_initialize
       \gobblespacetokens}
 
 \protected\def\page_fitting_stop_normal % todo: figure out why a small mp image gets shifted
diff --git a/tex/context/base/mkxl/tabl-frm.mkxl b/tex/context/base/mkxl/tabl-frm.mkxl
index ec530e7a4..4caa287f7 100644
--- a/tex/context/base/mkxl/tabl-frm.mkxl
+++ b/tex/context/base/mkxl/tabl-frm.mkxl
@@ -115,6 +115,7 @@
      \setupframed[\??framedtable][#2]%
    \fi
    \edef\currentframed{\??framedtable\currentframedtable}%
+   \pack_framed_initialize
    \c_tabl_framed_r\zerocount
    \d_tabl_framed_d\framedparameter\c!distance
    \framedparameter\c!before}
@@ -126,7 +127,7 @@
 % a two pass variant that deals with the height .. so no catcode changes here
 
 \tolerant\protected\def\pack_framed_start_framed_whatever[#1]%
-  {\pack_framed_initialize
+  {\pack_framed_initialize % moved up
    \bgroup
    \setupcurrentframed[#1]% here !
    \pack_framed_process_indeed
diff --git a/tex/context/base/mkxl/trac-deb.lmt b/tex/context/base/mkxl/trac-deb.lmt
index 13e3c7e70..6ac0f3e16 100644
--- a/tex/context/base/mkxl/trac-deb.lmt
+++ b/tex/context/base/mkxl/trac-deb.lmt
@@ -248,9 +248,11 @@ function tracers.printerror(specification)
             report_str(tracers.showlines(filename,linenumber,offset,tonumber(luaerrorline)))
             report_nl()
         end
-        local errname = tex.jobname .. "-error.log"
         if quitonerror then
-            table.save(errname,specification)
+            local name = tex.jobname or ""
+            if name ~= "" then
+                table.save(name .. "-error.log",specification)
+            end
             local help = specification.lasttexhelp
             if help and #help > 0 then
                 report_nl()
diff --git a/tex/context/base/mkxl/typo-lbx.lmt b/tex/context/base/mkxl/typo-lbx.lmt
index 00ba1cc7f..758f3c700 100644
--- a/tex/context/base/mkxl/typo-lbx.lmt
+++ b/tex/context/base/mkxl/typo-lbx.lmt
@@ -7,53 +7,67 @@ if not modules then modules = { } end modules ['typo-lbx'] = {
     license   = "see context related readme files"
 }
 
+local context      = context
+
 local tostring = tostring
 
-local nuts             = nodes.nuts
+local nuts              = nodes.nuts
+local tonut             = nodes.tonut
+local tonode            = nodes.tonode
 
-local left_box_code    = nodes.listcodes.left
-local right_box_code   = nodes.listcodes.right
-local hlist_code       = nodes.nodecodes.hlist
+local left_box_code     = nodes.listcodes.left
+local right_box_code    = nodes.listcodes.right
+local local_box_code    = nodes.listcodes["local"]
+local hlist_code        = nodes.nodecodes.hlist
 
-local getlist          = nuts.getlist
-local getprev          = nuts.getprev
-local getnext          = nuts.getnext
-local getattribute     = nuts.getattribute
-local gettail          = nuts.tail
-local getwidth         = nuts.getwidth
-local setlist          = nuts.setlist
-local setoffsets       = nuts.setoffsets
-local flushlist        = nuts.flushlist
-local takebox          = nuts.takebox
-local setbox           = nuts.setbox
-local copynode         = nuts.copynode
-local rangedimensions  = nuts.rangedimensions
-local traverse_list    = nuts.traversers.list
+-- some can go:
 
-local expandmacro      = token.expandmacro
+local getlist           = nuts.getlist
+local getprev           = nuts.getprev
+local getnext           = nuts.getnext
+local getattribute      = nuts.getattribute
+local gettail           = nuts.tail
+local getwidth          = nuts.getwidth
+local getboth           = nuts.getboth
+local getindex          = nuts.getindex
+local setlist           = nuts.setlist
+local flushlist         = nuts.flushlist
+local takebox           = nuts.takebox
+local setbox            = nuts.setbox
+local copynode          = nuts.copynode
+local rangedimensions   = nuts.rangedimensions
+local traverse_list     = nuts.traversers.list
 
-local dimension_value  = tokens.values.dimension
-local integer_value    = tokens.values.integer
+----- setlocalbox       = tex.setlocalbox -- todo: also in node.direct namespace
+----- getlocalbox       = tex.getlocalbox -- todo: also in node.direct namespace
 
-local implement        = interfaces.implement
+local expandmacro       = token.expandmacro
 
-typesetters            = typesetters or { }
-local typesetters      = typesetters
+local dimension_value   = tokens.values.dimension
+local integer_value     = tokens.values.integer
 
-typesetters.localboxes = typesetters.localboxes or { }
-local localboxes       = typesetters.localboxes
+local implement         = interfaces.implement
 
-local a_localboxes     = attributes.private("localboxes")
+typesetters             = typesetters or { }
+local typesetters       = typesetters
 
-local starttiming      = statistics.starttiming
-local stoptiming       = statistics.stoptiming
+typesetters.localboxes  = typesetters.localboxes or { }
+local localboxes        = typesetters.localboxes
 
-do
+local a_localboxesmark  = attributes.private("localboxesmark")
+
+local starttiming       = statistics.starttiming
+local stoptiming        = statistics.stoptiming
 
-    local lb_attribute        = 0
+do
+    local lb_found            = nil
+    local lb_class            = 0
     local lb_linenumber       = 0
-    local lb_width            = 0
-    local lb_offset           = 0
+    local lb_linewidth        = 0
+    local lb_localwidth       = 0
+    local lb_progress         = 0
+    local lb_leftoffset       = 0
+    local lb_rightoffset      = 0
     local lb_leftskip         = 0
     local lb_rightskip        = 0
     local lb_lefthang         = 0
@@ -63,10 +77,13 @@ do
     local lb_parfillrightskip = 0
     local lb_overshoot        = 0
 
-    implement { name = "localboxattribute",        public = true, usage = "value", actions = function() return integer_value,   lb_attribute        end }
+    implement { name = "localboxclass",            public = true, usage = "value", actions = function() return integer_value,   lb_class            end }
     implement { name = "localboxlinenumber",       public = true, usage = "value", actions = function() return integer_value,   lb_linenumber       end }
-    implement { name = "localboxwidth",            public = true, usage = "value", actions = function() return dimension_value, lb_width            end }
-    implement { name = "localboxoffset",           public = true, usage = "value", actions = function() return dimension_value, lb_offset           end }
+    implement { name = "localboxlinewidth",        public = true, usage = "value", actions = function() return dimension_value, lb_linewidth        end }
+    implement { name = "localboxlocalwidth",       public = true, usage = "value", actions = function() return dimension_value, lb_localwidth       end }
+    implement { name = "localboxprogress",         public = true, usage = "value", actions = function() return dimension_value, lb_progress         end }
+    implement { name = "localboxleftoffset",       public = true, usage = "value", actions = function() return dimension_value, lb_leftoffset       end }
+    implement { name = "localboxrightoffset",      public = true, usage = "value", actions = function() return dimension_value, lb_rightoffset      end }
     implement { name = "localboxleftskip",         public = true, usage = "value", actions = function() return dimension_value, lb_leftskip         end }
     implement { name = "localboxrightskip",        public = true, usage = "value", actions = function() return dimension_value, lb_rightskip        end }
     implement { name = "localboxlefthang",         public = true, usage = "value", actions = function() return dimension_value, lb_lefthang         end }
@@ -76,71 +93,115 @@ do
     implement { name = "localboxparfillrightskip", public = true, usage = "value", actions = function() return dimension_value, lb_parfillrightskip end }
     implement { name = "localboxovershoot",        public = true, usage = "value", actions = function() return dimension_value, lb_overshoot        end }
 
-    local function action(current,where)
-        -- We can have nested leftboxes!
-        local l = getlist(current)
-        setlist(current)
-        local h = copynode(current)
-        setlist(h,l)
-        setbox("localboxcontentbox",h)
-        expandmacro("localboxcommand") -- no longer pass arguments
-        local b = takebox("localboxcontentbox")
-        setlist(current,b)
-        if where == "left" then
-            local w = getwidth(b)
-            setoffsets(b,lb_width - lb_offset - w)
-        else
-            setoffsets(b,lb_offset - lb_width)
+    local cache = table.setmetatableindex(function(t,k)
+        local v = { n = 0, m = 0 }
+        t[k] = v
+        return v
+    end)
+
+    -- todo: use a simple usernode that refers to a cache so that we don't need to
+    -- make copies
+
+    implement {
+        name      = "localboxmarkonce",
+        public    = true,
+        arguments =  "integer",
+        actions   = function(attr)
+            local c = cache[attr]
+            local n = c.n
+-- first test this:
+--             if n == c.m then
+-- print("all false",attr,n)
+--                 -- all false
+--                 n = 1
+--                 c.m = 0
+--             else
+                n = n + 1
+--             end
+            c[n] = true
+            c.n = n
+            context(n)
+        end
+    }
+
+    local function action(current)
+        local list = getlist(current)
+        if list then
+            local attr = getattribute(list,a_localboxesmark) or 0
+            local cach = attr and cache[lb_class]
+            local once = cach and cach[attr]
+            if once == false then
+                setlist(current)
+                flushlist(list)
+            else
+                setlist(current)
+                local head = copynode(current)
+                setlist(head,list)
+                setbox("localboxcontentbox",head)
+                expandmacro("localboxcommand") -- no longer pass arguments
+                local box = takebox("localboxcontentbox")
+                setlist(current,box)
+                if once and cach[attr] == true then
+                    cach[attr] = false
+                    cach.m = cach.m + 1
+                end
+            end
         end
     end
 
-    local function processleftbox(box,width)
+    -- these two are now more or less the same so ...
+
+    local function processleftbox(box)
         local list = getlist(box)
-        if not width then
-            width = 0
-        end
         for current, id, subtype in traverse_list, list do
-            if id == hlist_code then
-                local a = getattribute(current,a_localboxes)
-                if a then
-                    lb_attribute = a
-                    lb_width     = width + rangedimensions(box,list,getprev(current))
-                    action(current,"left")
-                end
-                if subtype == left_box_code then
-                    processleftbox(current,width + rangedimensions(box,list,getprev(current)))
+            if subtype == local_box_code and getwidth(current) == 0 then
+                local class = getindex(current)
+                if class then
+                    lb_found    = current
+                    lb_class    = class
+                    lb_progress = rangedimensions(box,list,current)
+                    action(current)
                 end
             end
         end
     end
 
-    local function processrightbox(box,width)
+    local function processrightbox(box)
         local list = getlist(box)
-        local tail = gettail(list)
-        if not width then
-            width = 0
-        end
         for current, id, subtype in traverse_list, list do
-            if id == hlist_code then
-                local a = getattribute(current,a_localboxes)
-                if a then
-                    lb_attribute = a
-                    lb_width     = width + rangedimensions(box,list,getnext(current),tail)
-                    action(current,"right")
+            if subtype == local_box_code and getwidth(current) == 0 then
+                local class = getindex(current)
+                if class then
+                    lb_found    = current
+                    lb_class    = class
+                    lb_progress = rangedimensions(box,list,current)
+                    action(current)
                 end
-                if subtype == right_box_code then
-                    processrightbox(current,width + rangedimensions(box,getnext(current),tail))
+            end
+        end
+    end
+
+    local function processmiddlebox(box,line)
+        local list = getlist(box)
+        for current, id, subtype in traverse_list, list do
+            if subtype == local_box_code and getwidth(current) == 0 then
+                local class = getindex(current)
+                if class then
+                    lb_found    = current
+                    lb_class    = class
+                    lb_progress = rangedimensions(line,getlist(line),box)
+                    action(current)
                 end
             end
         end
     end
 
-    local function processlocalboxes(line, leftbox, rightbox, linenumber, leftskip, rightskip, lefthang, righthang, indent, parfillleftskip, parfillrightskip, overshoot)
+    local function processlocalboxes(line,leftbox,rightbox,middlebox,linenumber,leftskip,rightskip,lefthang,righthang,indent,parfillleftskip,parfillrightskip,overshoot)
         --
-        lb_attribute        = 0
+        lb_found            = nil
+        lb_class            = 0
         lb_linenumber       = linenumber
-        lb_width            = 0
-     -- lb_offset           = 0
+        lb_progress         = 0
         lb_leftskip         = leftskip
         lb_rightskip        = rightskip
         lb_lefthang         = lefthang
@@ -149,15 +210,19 @@ do
         lb_parfillleftskip  = parfillleftskip
         lb_parfillrightskip = parfillrightskip
         lb_overshoot        = overshoot
-        --
-        -- for now we always anchor
-        --
+        lb_linewidth        = getwidth(line)
+        lb_leftoffset       = leftskip  + lefthang  + parfillleftskip  + indent
+        lb_rightoffset      = rightskip + righthang + parfillrightskip - overshoot
         if leftbox then
-            lb_offset = leftskip + lefthang + indent + parfillleftskip + getwidth(leftbox)
+            lb_localwidth = getwidth(leftbox)
             processleftbox(leftbox)
         end
+        if middlebox then
+            lb_localwidth = getwidth(middlebox)
+            processmiddlebox(middlebox,line)
+        end
         if rightbox then
-            lb_offset = rightskip + righthang + parfillrightskip + getwidth(rightbox) - overshoot
+            lb_localwidth = getwidth(rightbox)
             processrightbox(rightbox)
         end
     end
diff --git a/tex/context/base/mkxl/typo-lbx.mkxl b/tex/context/base/mkxl/typo-lbx.mkxl
index f8d252a27..0310a441f 100644
--- a/tex/context/base/mkxl/typo-lbx.mkxl
+++ b/tex/context/base/mkxl/typo-lbx.mkxl
@@ -13,10 +13,11 @@
 
 \writestatus{loading}{ConTeXt Typesetting Macros / Local Boxes}
 
-% musical timestamp: New Scary Goldings ft. John Scofield MonoNeon & Louis Cole (late
-% October 2021)
+% This time the usual musical timestamp is: New Scary Goldings ft. John Scofield
+% MonoNeon & Louis Cole (late October 2021) (plus the playlist in loop mode) and
+% further improved after watching Cory Wong's LIVE IN MPLS (9 FEB 2019) concert.
 
-% maybe: \iflocalleftbox
+% maybe: \iflocalbox 0/1/2
 
 \registerctxluafile{typo-lbx}{autosuffix}
 
@@ -27,18 +28,18 @@
 %D many instances at the same time add some complizity. Therefore, for the moment it's
 %D a playground.
 
-
 \unprotect
 
-\def\v!lefttext {lefttext}
-\def\v!righttext{righttext}
+\def\typo_localboxes_reset
+  {\localleftbox  {}% no class here, works grouped
+   \localrightbox {}%
+   \localmiddlebox{}}
 
 \appendtoks
-    \localleftbox {}% \nolocalboxes : we don't have a nice command category for it
-    \localrightbox{}%
+    \typo_localboxes_reset
 \to\everyforgetall
 
-\definesystemattribute[localboxes][public]
+\definesystemattribute[localboxesmark][public]
 
 %D We used to pass arguments but there might be many so ...
 
@@ -48,13 +49,18 @@
 \installcorenamespace{localboxesattribute}
 \installcorenamespace{localboxesnamespace}
 \installcorenamespace{localboxeslocations}
+\installcorenamespace{localboxesresetters}
 
 \installcommandhandler \??localboxes {localboxes} \??localboxes
 
 \setuplocalboxes
-  [\c!location=\v!left]
+  [\c!command=\localboxcontent,
+   \c!width=\zeropoint,
+   \c!location=\v!left,
+   \c!distance=\zeropoint]
 
 \newcount\c_typo_localboxes
+\newcount\c_typo_localboxes_class
 
 \appendtoks
     \global\advance\c_typo_localboxes\plusone
@@ -62,33 +68,29 @@
     \gletcsname\??localboxesnamespace\number\c_typo_localboxes\endcsname\currentlocalboxes
 \to \everydefinelocalboxes
 
-%D The optional argument forces seting the \quote {whole} paragraph properties (which is needed
+%D The optional argument forces setting the \quote {whole} paragraph properties (which is needed
 %D when the assignment happens after e.g.\ \type {\everypar} but is also meant for the first
 %D line.
 
+%D Todo: reserve class 1 for this:
+
 \def\typo_paragraphs_l#1{\localleftbox \ifcstok{#1}\v!global par\fi}
 \def\typo_paragraphs_r#1{\localrightbox\ifcstok{#1}\v!global par\fi}
 
-\permanent\tolerant\protected\def\leftparbox        [#1]{\typo_paragraphs_l{#1}\bgroup\enforced\let\leftparbox \relax\let\next}
-\permanent\tolerant\protected\def\rightparbox       [#1]{\typo_paragraphs_r{#1}\bgroup\enforced\let\rightparbox\relax\let\next}
-
-\permanent\tolerant\protected\def\appendleftparbox  [#1]{\dowithnextbox{\leftparbox [#1]{\the\localleftbox \unhbox\nextbox}}\hbox}
-\permanent\tolerant\protected\def\appendrightparbox [#1]{\dowithnextbox{\rightparbox[#1]{\the\localrightbox\unhbox\nextbox}}\hbox}
-
-\permanent\tolerant\protected\def\prependleftparbox [#1]{\dowithnextbox{\leftparbox [#1]{\unhbox\nextbox\the\localleftbox }}\hbox}
-\permanent\tolerant\protected\def\prependrightparbox[#1]{\dowithnextbox{\rightparbox[#1]{\unhbox\nextbox\the\localrightbox}}\hbox}
-
-\permanent\tolerant\protected\def\resetleftparbox   [#1]{\typo_paragraphs_l{#1}{}}
-\permanent\tolerant\protected\def\resetrightparbox  [#1]{\typo_paragraphs_r{#1}{}}
+\permanent\tolerant\protected\def\leftparbox [#1]{\typo_paragraphs_l{#1}\bgroup\enforced\let\leftparbox \relax\let\next}
+\permanent\tolerant\protected\def\rightparbox[#1]{\typo_paragraphs_r{#1}\bgroup\enforced\let\rightparbox\relax\let\next}
 
 % called back:
 
+\permanent\protected\def\localboxcontent
+  {\box\localboxcontentbox}
+
 \permanent\protected\def\localboxcommand
-  {\ifcsname\??localboxesnamespace\number\localboxattribute\endcsname
+  {\ifcsname\??localboxesnamespace\number\localboxclass\endcsname
     %\edef\currentlocalboxes{\lastnamedcs}%
      \expandafter\let\expandafter\currentlocalboxes\lastnamedcs
      \setbox\localboxcontentbox\hbox
-       {\uselocalboxesstyleandcolor\c!style\c!color
+       {\uselocalboxesstyleandcolor\c!style\c!color % sometimes redundant
         \localboxesparameter\c!command}%
    \fi}
 
@@ -96,51 +98,79 @@
 %D existing local box we create nested ones. This is handled in the callback but if
 %D really needed one can do something like (do we need a primitive?):
 
-% \localrightbox{%
-%   \the\localrightbox
-%   \setbox\scratchbox\lastbox
-%   \unhbox\scratchbox
-%   additional}%
+\def\typo_localboxes_localbox
+  {\ifx\currentlocalboxeslocation\v!right
+     \localrightbox
+   \orelse\ifx\currentlocalboxeslocation\v!left
+     \localleftbox
+   \else
+     \localmiddlebox
+   \fi}
 
-\def\typo_localboxes_zero#1#2%
-  {\ifcsname\??localboxesattribute#1\endcsname
-     \hpack attr \localboxesattribute \lastnamedcs to \zeropoint \bgroup
-        \edef\currentlocalboxes{#1}%
-        #2%
-     \egroup
+\def\typo_localboxes_zero#1#2#3%
+  {\ifcsname\??localboxesattribute#2\endcsname
+     \c_typo_localboxes_class\lastnamedcs
+     \edef\currentlocalboxes{#2}%
+     \edef\currentlocalboxeslocation{#1}%
+     \typo_localboxes_localbox
+        class \c_typo_localboxes_class
+        \bgroup
+          \hpack
+            \ifcstok{\localboxesparameter\c!repeat}\v!no
+              attr \localboxesmarkattribute \localboxmarkonce\c_typo_localboxes_class\relax
+            \fi
+            to \zeropoint
+          \bgroup
+            \uselocalboxesstyleandcolor\c!style\c!color
+            \hbox{#3}%
+            \hss
+          \egroup
+        \egroup
+   \fi}
+
+\def\typo_localboxes_asis#1#2#3%
+  {\ifcsname\??localboxesattribute#2\endcsname
+     \c_typo_localboxes_class\lastnamedcs
+     \edef\currentlocalboxes{#2}%
+     \edef\currentlocalboxeslocation{#1}%
+     \typo_localboxes_localbox
+        class \c_typo_localboxes_class
+        \bgroup
+          \hpack
+            \ifcstok{\localboxesparameter\c!repeat}\v!no
+              attr \localboxesmarkattribute \localboxmarkonce\c_typo_localboxes_class\relax
+            \fi
+            % todo: use width if dimension, use distance if given
+          \bgroup
+            \uselocalboxesstyleandcolor\c!style\c!color
+            \hbox{#3}% no \hss
+          \egroup
+        \egroup
    \fi}
 
-\def\typo_localboxes_asis#1#2%
-  {\hpack \bgroup  % todo: use width if dimension, use distance if given
+\defcsname\??localboxeslocations\v!left     \endcsname{\typo_localboxes_zero\v!left  }
+\defcsname\??localboxeslocations\v!right    \endcsname{\typo_localboxes_zero\v!right }
+\defcsname\??localboxeslocations\v!lefttext \endcsname{\typo_localboxes_asis\v!left  }
+\defcsname\??localboxeslocations\v!righttext\endcsname{\typo_localboxes_asis\v!right }
+\defcsname\??localboxeslocations\v!middle   \endcsname{\typo_localboxes_asis\v!middle}
+
+\letcsname\??localboxesresetters\v!left     \endcsname\v!left
+\letcsname\??localboxesresetters\v!right    \endcsname\v!right
+\letcsname\??localboxesresetters\v!lefttext \endcsname\v!left
+\letcsname\??localboxesresetters\v!righttext\endcsname\v!right
+\letcsname\??localboxesresetters\v!middle   \endcsname\v!middle
+
+\permanent\tolerant\protected\def\resetlocalbox[#1]%
+  {\ifcsname\??localboxesattribute#1\endcsname
+     \c_typo_localboxes_class\lastnamedcs
      \edef\currentlocalboxes{#1}%
-     \localboxesparameter\c!command{#2}%
-   \egroup}
-
-\defcsname\??localboxeslocations\v!left\endcsname#1#2%
-  {\leftparbox \bgroup
-     \typo_localboxes_zero{#1}{#2}%
-     \the\localleftbox
-   \egroup}
-
-\defcsname\??localboxeslocations\v!right\endcsname#1#2%
-  {\rightparbox \bgroup
-     \the\localrightbox
-     \typo_localboxes_zero{#1}{#2}%
-   \egroup}
-
-\defcsname\??localboxeslocations\v!lefttext\endcsname#1#2%
-  {\leftparbox \bgroup
-     \typo_localboxes_asis{#1}{#2}%
-     \the\localleftbox
-   \egroup}
-
-\defcsname\??localboxeslocations\v!righttext\endcsname#1#2%
-  {\rightparbox \bgroup
-     \the\localrightbox
-     \typo_localboxes_asis{#1}{#2}%
-   \egroup}
+     \ifcsname\??localboxesresetters\localboxesparameter\c!location\endcsname
+       \edef\currentlocalboxeslocation{\lastnamedcs}%
+       \typo_localboxes_localbox class \c_typo_localboxes_class {}%
+     \fi
+   \fi}
 
-\permanent\tolerant\protected\def\localbox[#1]%
+\def\typo_localboxes_box#1%
   {\dowithnextboxcontent
      {\edef\currentlocalboxes{#1}%
       \uselocalboxesstyleandcolor\c!style\c!color}
@@ -148,8 +178,11 @@
         \expandafter\lastnamedcs
       \else
         \csname\??localboxeslocations\v!left\expandafter\endcsname
-      \fi{#1}{\unhbox\nextbox}}%
-     \hbox}
+      \fi{#1}{\unhbox\nextbox}}}
+
+
+\permanent\tolerant\protected\def\localbox[#1]%
+  {\typo_localboxes_box{#1}\hbox}
 
 \permanent\tolerant\protected\def\startlocalbox[#1]%
   {\dowithnextbox
@@ -166,6 +199,120 @@
 
 \aliased\let\stoplocalbox\donothing
 
+\permanent\tolerant\protected\def\startlocalboxrange[#1]%
+  {\globalpushmacro\stoplocalboxrange
+   \ifcsname\??localboxeslocations\namedlocalboxesparameter{#1}\c!location\endcsname
+     \lastnamedcs{#1}{}%
+   \fi}
+
+\permanent\protected\def\stoplocalboxrange
+  {\globalpopmacro\stoplocalboxrange}%
+
+% using left and right with left lagging behind:
+%
+% \permanent\protected\def\localmarginlefttext#1%
+%   {\setbox\localboxcontentbox\hpack
+%      {\unhbox\localboxcontentbox
+%       \setbox\localboxcontentbox\lastbox
+%       \unhbox\localboxcontentbox}%
+%    \hpack xoffset -\dimexpr
+%       #1
+%      +\localboxprogress
+%      +\localboxleftoffset
+%      +\wd\localboxcontentbox
+%      +\localboxesparameter\c!distance
+%    \relax{\box\localboxcontentbox}}
+%
+% \permanent\protected\def\localmarginrighttext#1%
+%   {\hpack xoffset \dimexpr
+%       #1
+%      +\localboxrightoffset
+%      +\localboxlocalwidth
+%      -\localboxprogress
+%      +\localboxesparameter\c!distance
+%    \relax{\box\localboxcontentbox}}
+
+% using middle:
+
+\permanent\protected\def\localmarginlefttext#1%
+  {\ifzeropt\localboxesparameter\c!width\relax
+     % a but ugly hack ... for now
+     \setbox\localboxcontentbox\hpack
+       {\unhbox\localboxcontentbox
+        \setbox\localboxcontentbox\lastbox
+        \unhbox\localboxcontentbox}%
+   \fi
+   \hpack xoffset \dimexpr
+     -#1
+     -\localboxprogress
+     -\wd\localboxcontentbox
+     -\localboxesparameter\c!distance
+   \relax{\box\localboxcontentbox}}
+
+\permanent\protected\def\localmarginrighttext#1%
+  {\hpack xoffset \dimexpr
+      #1
+     +\localboxlinewidth
+     -\localboxprogress
+     +\localboxesparameter\c!distance
+   \relax{\box\localboxcontentbox}}
+
+% todo: use generic one above
+
+\permanent\protected\def\localmargintext[#1]#2%
+  {\dontleavehmode
+   \ifcsname\??localboxesattribute#1\endcsname
+     \c_typo_localboxes_class\lastnamedcs
+     \edef\currentlocalboxes{#1}%
+     \edef\currentlocalboxeslocation{\localboxesparameter\c!location}%
+     \ifx\currentlocalboxeslocation\v!right\localrightbox\orelse\ifx\currentlocalboxeslocation\v!left\localleftbox\else\localmiddlebox\fi
+        class \c_typo_localboxes_class
+        \bgroup
+          \hpack
+            \ifcstok{\localboxesparameter\c!repeat}\v!no
+              attr \localboxesmarkattribute \localboxmarkonce\c_typo_localboxes_class\relax
+            \fi
+            to \zeropoint
+          \bgroup
+            \uselocalboxesstyleandcolor\c!style\c!color
+            \hbox{#2}%
+            \hss
+          \egroup
+        \egroup
+   \fi}
+
+\definelocalboxes
+  [\v!leftmargin]
+  [\c!command=\localmarginlefttext\zeropoint,
+   \c!repeat=\v!no,
+   \c!distance=\leftmargindistance,
+ % \c!location=\v!left]
+   \c!location=\v!middle]
+
+\definelocalboxes
+  [\v!rightmargin]
+  [\c!command=\localmarginrighttext\zeropoint,
+   \c!repeat=\v!no,
+   \c!distance=\rightmargindistance,
+ % \c!location=\v!right]
+   \c!location=\v!middle]
+
+\definelocalboxes
+  [\v!leftedge]
+  [\c!command=\localmarginlefttext\leftmargintotal,
+   \c!repeat=\v!no,
+   \c!distance=\leftedgedistance,
+ % \c!location=\v!left]
+   \c!location=\v!middle]
+
+\definelocalboxes
+  [\v!rightedge]
+  [\c!command=\localmarginrighttext\rightmargintotal,
+   \c!repeat=\v!no,
+   \c!distance=\rightedgedistance,
+ % \c!location=\v!right]
+   \c!location=\v!middle]
+
 %D Here is an example of usage:
 
 %D \starttyping
diff --git a/tex/context/fonts/mkiv/ebgaramond.lfg b/tex/context/fonts/mkiv/ebgaramond.lfg
index 43cc13c51..73f3e6b70 100644
--- a/tex/context/fonts/mkiv/ebgaramond.lfg
+++ b/tex/context/fonts/mkiv/ebgaramond.lfg
@@ -4,6 +4,44 @@ return {
     comment = "Goodies that complement eb garamond.",
     author = "Hans Hagen",
     copyright = "ConTeXt development team",
+    mathematics = {
+        tweaks = {
+            aftercopying = {
+                function(target,original,...)
+                    local crap = {
+                        [0x1D453] = { .20, 1.20 },
+                        [0x1D454] = { .15, 1.15 },
+                    }
+                    local characters = target.characters
+                    local function adapt(k,v)
+                        local character = characters[k]
+                        local width     = character.width
+                        character.width = v[2]*width
+                     -- character.commands = { { "offset", v[1]*width, 0, k } }
+                        character.xoffset = v[1]*width
+                        local smaller = original.characters[k].smaller
+                        if smaller and smaller ~= k then
+                            adapt(smaller,v)
+                        end
+                    end
+                    for k, v in next, crap do
+                        adapt(k,v)
+                    end
+                end,
+            },
+        },
+
+        alternates = {
+            partial        = { feature = 'ss02', value = 1, comment = "Curved partial" },
+            semibold       = { feature = 'ss04', value = 1, comment = "Semibold" },
+            extrabold      = { feature = 'ss05', value = 1, comment = "Extrabold" },
+            hbar           = { feature = 'ss06', value = 1, comment = "Horizontal bar for h-bar" },
+            integral       = { feature = 'ss07', value = 1, comment = "A more slanted integral sign" },
+            tilde          = { feature = 'ss09', value = 1, comment = "A tilde variant" },
+            outbendingh    = { feature = 'ss10', value = 1, comment = "Out-bending h" },
+            largeoperators = { feature = 'ss11', value = 1, comment = "Larger operators" },
+        },
+    },
     designsizes = {
         ["EBGaramond-Italic"] = {
             ["8pt"]   = "file:EBGaramond08-Italic",
diff --git a/tex/context/fonts/mkiv/libertinus-math.lfg b/tex/context/fonts/mkiv/libertinus-math.lfg
index b6621b946..c02f0506a 100644
--- a/tex/context/fonts/mkiv/libertinus-math.lfg
+++ b/tex/context/fonts/mkiv/libertinus-math.lfg
@@ -13,29 +13,67 @@ return {
     mathematics = {
         tweaks = {
             aftercopying = {
+             -- function(target,original)
+             --     local okay = 983068
+             --     local crap = {
+             --         ["minute"] = "minute.ssty1",
+             --         ["second"] = "second.ssty1",
+             --      -- [8242] = 983068,
+             --      -- [8243] = 983069,
+             --         [8244] = 983070,
+             --         [8245] = 983071,
+             --         [8246] = 983072,
+             --         [8247] = 983073,
+             --     }
+             --     local characters = target.characters
+             --     local unicodes   = original.resources.unicodes
+             --     if unicodes["minute.ssty1"] == okay then
+             --         for old, new in next, crap do
+             --             if type(old) == "string" then
+             --                 old = unicodes[old]
+             --             end
+             --             if type(new) == "string" then
+             --                 new = unicodes[new]
+             --             end
+             --             if old and new and characters[old] then
+             --                 local c = characters[new]
+             --                 if c then
+             --                     characters[old] = c
+             --                     c.commands = { { "up", .06 * c.height }, { "slot", 0, new, .7 } }
+             --                 end
+             --             end
+             --         end
+             --         local four = characters[0x2057]
+             --         if four then
+             --             local one = characters[okay]
+             --             local owd = .75*one.width
+             --             local off = .6*one.height
+             --             four.width = 4*owd
+             --             four.commands = {
+             --                 { "offset",     0, off, okay },
+             --                 { "offset",   owd, off, okay },
+             --                 { "offset", 2*owd, off, okay },
+             --                 { "offset", 3*owd, off, okay },
+             --             }
+             --         else
+             --             -- we don't add (but we could), just patch, and there's no
+             --             -- reverse quad either
+             --         end
+             --     else
+             --         logs.report("fonts","the libertinus tweaks need to be checked")
+             --     end
+             -- end,
                 function(target,original)
-                    local okay = 983068
-                    local crap = {
-                        ["minute"] = "minute.ssty1",
-                        ["second"] = "second.ssty1",
-                     -- [8242] = 983068,
-                     -- [8243] = 983069,
-                        [8244] = 983070,
-                        [8245] = 983071,
-                        [8246] = 983072,
-                        [8247] = 983073,
-                    }
+                    local crap = { 0x2032, 0x2033, 0x2034, 0x2036, 0x2037, 0x2038 } -- 0x2057
                     local characters = target.characters
+                    local originals  = original.characters
                     local unicodes   = original.resources.unicodes
-                    if unicodes["minute.ssty1"] == okay then
-                        for old, new in next, crap do
-                            if type(old) == "string" then
-                                old = unicodes[old]
-                            end
-                            if type(new) == "string" then
-                                new = unicodes[new]
-                            end
-                            if old and new and characters[old] then
+                    for i=1,#crap do
+                        local old = crap[i]
+                        local chr = characters[slot]
+                        if chr then
+                            local new = chr.smaller
+                            if new then
                                 local c = characters[new]
                                 if c then
                                     characters[old] = c
@@ -43,28 +81,22 @@ return {
                                 end
                             end
                         end
-                        local four = characters[0x2057]
-                        if four then
-                            local one = characters[okay]
-                            local owd = .75*one.width
-                            local off = .6*one.height
-                            four.width = 4*owd
-                            four.commands = {
-                                { "offset",     0, off, okay },
-                                { "offset",   owd, off, okay },
-                                { "offset", 2*owd, off, okay },
-                                { "offset", 3*owd, off, okay },
-                            }
-                        else
-                            -- we don't add (but we could), just patch, and there's no
-                            -- reverse quad either
-                        end
-                    else
-                        logs.report("fonts","the libertinus tweaks need to be checked")
+                    end
+                    local four = characters[0x2057]
+                    if four then
+                        local one = characters[0x2032]
+                        local owd = .75*one.width
+                        local off = .6*one.height
+                        four.width = 4*owd
+                        four.commands = {
+                            { "offset",     0, off, okay },
+                            { "offset",   owd, off, okay },
+                            { "offset", 2*owd, off, okay },
+                            { "offset", 3*owd, off, okay },
+                        }
                     end
                 end,
             },
         },
     },
 }
-
diff --git a/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv b/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv
index 5cafe503f..87f8b5cad 100644
--- a/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv
+++ b/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv
@@ -57,19 +57,25 @@
   %     \definetypeface [ebgaramond] [mm] [math]  [bonum]      [default] [rscale=0.8] % rather arbitrary but seldom mixed anyway
   % \stoptypescript
 
-    \starttypescript [serif] [ebgaramond]
+    \starttypescript [\s!serif] [ebgaramond]
         \setups[font:fallback:serif]
-        \definefontsynonym [Serif]          [file:ebgaramond-regular]   [features=eb-garamond-normal]
-        \definefontsynonym [SerifItalic]    [file:ebgaramond-italic]    [features=eb-garamond-normal]
-        \definefontsynonym [SerifBold]      [file:ebgaramond-bold]      [features=eb-garamond-normal]
-        \definefontsynonym [SerifBoldItalic][file:ebgaramond-bolditalic][features=eb-garamond-normal]
-        \definefontsynonym [SerifCaps]      [Serif]                     [features=eb-garamond-smallcaps]
+        \definefontsynonym [\s!Serif]          [\s!file:ebgaramond-regular]   [\s!features=eb-garamond-normal]
+        \definefontsynonym [\s!SerifItalic]    [\s!file:ebgaramond-italic]    [\s!features=eb-garamond-normal]
+        \definefontsynonym [\s!SerifBold]      [\s!file:ebgaramond-bold]      [\s!features=eb-garamond-normal]
+        \definefontsynonym [\s!SerifBoldItalic][\s!file:ebgaramond-bolditalic][\s!features=eb-garamond-normal]
+        \definefontsynonym [\s!SerifCaps]      [\s!Serif]                     [\s!features=eb-garamond-smallcaps]
+    \stoptypescript
+
+    \starttypescript [\s!math] [ebgaramond] [\s!name]
+        \loadfontgoodies[ebgaramond]
+        \definefontsynonym [\s!MathRoman] [\s!file:garamond-math.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=ebgaramond]
     \stoptypescript
 
     \starttypescript[ebgaramond]
-        \definetypeface [ebgaramond] [rm] [serif] [ebgaramond] [default]
-        \definetypeface [ebgaramond] [tt] [mono]  [dejavu]     [default] [rscale=0.8] % rather arbitrary but seldom mixed anyway
-        \definetypeface [ebgaramond] [mm] [math]  [bonum]      [default] [rscale=0.8] % rather arbitrary but seldom mixed anyway
+        \definetypeface [ebgaramond] [\s!rm] [\s!serif] [ebgaramond] [\s!default]
+        \definetypeface [ebgaramond] [\s!tt] [\s!mono]  [dejavu]     [\s!default] [\s!rscale=0.8] % rather arbitrary but seldom mixed anyway
+      % \definetypeface [ebgaramond] [\s!mm] [\s!math]  [bonum]      [\s!default] [\s!rscale=0.8] % rather arbitrary but seldom mixed anyway
+        \definetypeface [ebgaramond] [\s!mm] [\s!math]  [ebgaramond] [\s!default]
     \stoptypescript
 
 \stoptypescriptcollection
diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml
index 88cd1886b..06da1c646 100644
--- a/tex/context/interface/mkii/keys-en.xml
+++ b/tex/context/interface/mkii/keys-en.xml
@@ -318,6 +318,7 @@
 		<cd:variable name='lefthanging' value='lefthanging'/>
 		<cd:variable name='leftmargin' value='leftmargin'/>
 		<cd:variable name='leftpage' value='leftpage'/>
+		<cd:variable name='lefttext' value='lefttext'/>
 		<cd:variable name='lefttoright' value='lefttoright'/>
 		<cd:variable name='legend' value='legend'/>
 		<cd:variable name='less' value='less'/>
@@ -479,6 +480,7 @@
 		<cd:variable name='righthanging' value='righthanging'/>
 		<cd:variable name='rightmargin' value='rightmargin'/>
 		<cd:variable name='rightpage' value='rightpage'/>
+		<cd:variable name='righttext' value='righttext'/>
 		<cd:variable name='righttoleft' value='righttoleft'/>
 		<cd:variable name='roman' value='roman'/>
 		<cd:variable name='romannumerals' value='romannumerals'/>
diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml
index 447cfd580..ead51a685 100644
--- a/tex/context/interface/mkii/keys-ro.xml
+++ b/tex/context/interface/mkii/keys-ro.xml
@@ -318,6 +318,7 @@
 		<cd:variable name='lefthanging' value='lefthanging'/>
 		<cd:variable name='leftmargin' value='marginestanga'/>
 		<cd:variable name='leftpage' value='paginastanga'/>
+		<cd:variable name='lefttext' value='textstanga'/>
 		<cd:variable name='lefttoright' value='lefttoright'/>
 		<cd:variable name='legend' value='legenda'/>
 		<cd:variable name='less' value='less'/>
@@ -479,6 +480,7 @@
 		<cd:variable name='righthanging' value='righthanging'/>
 		<cd:variable name='rightmargin' value='marginedreapta'/>
 		<cd:variable name='rightpage' value='paginadreapta'/>
+		<cd:variable name='righttext' value='textdreapta'/>
 		<cd:variable name='righttoleft' value='righttoleft'/>
 		<cd:variable name='roman' value='roman'/>
 		<cd:variable name='romannumerals' value='numereromane'/>
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 27a2037c1..9ecdb0f6f 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  : 2021-10-28 10:17
+-- merge date  : 2021-11-02 09:59
 
 do -- begin closure to overcome local limits and interference
 
-- 
cgit v1.2.3