From 7fd782dace8f90e7e032ca8f449f8ca4eada450b Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Fri, 21 May 2021 15:21:45 +0200
Subject: 2021-05-21 15:05: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/mkiv/char-ini.mkiv                |   1 +
 tex/context/base/mkiv/char-scr.lua                 | 161 ++++++++++++++
 tex/context/base/mkiv/cont-new.mkiv                |   2 +-
 tex/context/base/mkiv/context.mkiv                 |   2 +-
 tex/context/base/mkiv/scrp-cjk.lua                 |   2 +-
 tex/context/base/mkiv/scrp-ini.lua                 | 159 +-------------
 tex/context/base/mkiv/status-files.pdf             | Bin 23933 -> 23937 bytes
 tex/context/base/mkiv/status-lua.pdf               | Bin 229263 -> 229293 bytes
 tex/context/base/mkxl/char-ini.mkxl                |   1 +
 tex/context/base/mkxl/cont-new.mkxl                |   2 +-
 tex/context/base/mkxl/context.mkxl                 |   2 +-
 tex/context/base/mkxl/scrp-ini.lmt                 | 159 +-------------
 tex/context/interface/mkii/keys-en.xml             |   2 +
 tex/context/modules/mkxl/m-mathfun.mkxl            | 231 +++++++++++++++++++++
 tex/generic/context/luatex/luatex-fonts-merged.lua |   2 +-
 18 files changed, 408 insertions(+), 324 deletions(-)
 create mode 100644 tex/context/base/mkiv/char-scr.lua
 create mode 100644 tex/context/modules/mkxl/m-mathfun.mkxl

(limited to 'tex')

diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 8f9793d5b..823e34bbc 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.05.20 15:57}
+\newcontextversion{2021.05.21 15:02}
 
 %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 45e9cc413..ba05ebfc6 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.05.20 15:57}
+\edef\contextversion{2021.05.21 15:02}
 
 %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 76a626954..a21723db8 100644
--- a/tex/context/base/mkii/mult-en.mkii
+++ b/tex/context/base/mkii/mult-en.mkii
@@ -141,6 +141,7 @@
 \setinterfacevariable{chemistry}{chemistry}
 \setinterfacevariable{cite}{cite}
 \setinterfacevariable{closed}{closed}
+\setinterfacevariable{collapsed}{collapsed}
 \setinterfacevariable{color}{color}
 \setinterfacevariable{column}{column}
 \setinterfacevariable{columns}{columns}
@@ -392,6 +393,7 @@
 \setinterfacevariable{nostopper}{nostopper}
 \setinterfacevariable{not}{not}
 \setinterfacevariable{notation}{notation}
+\setinterfacevariable{notcollapsed}{notcollapsed}
 \setinterfacevariable{note}{note}
 \setinterfacevariable{nothanging}{nothanging}
 \setinterfacevariable{nothyphenated}{nothyphenated}
diff --git a/tex/context/base/mkiv/char-ini.mkiv b/tex/context/base/mkiv/char-ini.mkiv
index aa3d31ba8..384ae983f 100644
--- a/tex/context/base/mkiv/char-ini.mkiv
+++ b/tex/context/base/mkiv/char-ini.mkiv
@@ -17,6 +17,7 @@
 \registerctxluafile{char-map}{} % maybe we will load this someplace else
 \registerctxluafile{char-tex}{}
 \registerctxluafile{char-ent}{}
+\registerctxluafile{char-scr}{}
 
 \unprotect
 
diff --git a/tex/context/base/mkiv/char-scr.lua b/tex/context/base/mkiv/char-scr.lua
new file mode 100644
index 000000000..692133814
--- /dev/null
+++ b/tex/context/base/mkiv/char-scr.lua
@@ -0,0 +1,161 @@
+if not modules then modules = { } end modules ['char-scr'] = {
+    version   = 1.001,
+    comment   = "companion to char-ini.mkiv",
+    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+    copyright = "PRAGMA ADE / ConTeXt Development Team",
+    license   = "see context related readme files"
+}
+
+local tonumber = tonumber
+
+characters.scripthash = { -- we could put these presets in char-def.lua
+    --
+    -- half width opening parenthesis
+    --
+    [0x0028] = "half_width_open",
+    [0x005B] = "half_width_open",
+    [0x007B] = "half_width_open",
+    [0x2018] = "half_width_open", -- ‘
+    [0x201C] = "half_width_open", -- “
+    --
+    -- full width opening parenthesis
+    --
+    [0x3008] = "full_width_open", -- 〈   Left book quote
+    [0x300A] = "full_width_open", -- 《   Left double book quote
+    [0x300C] = "full_width_open", -- 「   left quote
+    [0x300E] = "full_width_open", -- 『   left double quote
+    [0x3010] = "full_width_open", -- 【   left double book quote
+    [0x3014] = "full_width_open", -- 〔   left book quote
+    [0x3016] = "full_width_open", --〖   left double book quote
+    [0x3018] = "full_width_open", --     left tortoise bracket
+    [0x301A] = "full_width_open", --     left square bracket
+    [0x301D] = "full_width_open", --     reverse double prime qm
+    [0xFF08] = "full_width_open", -- (   left parenthesis
+    [0xFF3B] = "full_width_open", -- [   left square brackets
+    [0xFF5B] = "full_width_open", -- {   left curve bracket
+    --
+    -- half width closing parenthesis
+    --
+    [0x0029] = "half_width_close",
+    [0x005D] = "half_width_close",
+    [0x007D] = "half_width_close",
+    [0x2019] = "half_width_close", -- ’   right quote, right
+    [0x201D] = "half_width_close", -- ”   right double quote
+    --
+    -- full width closing parenthesis
+    --
+    [0x3009] = "full_width_close", -- 〉   book quote
+    [0x300B] = "full_width_close", -- 》   double book quote
+    [0x300D] = "full_width_close", -- 」   right quote, right
+    [0x300F] = "full_width_close", -- 』   right double quote
+    [0x3011] = "full_width_close", -- 】   right double book quote
+    [0x3015] = "full_width_close", -- 〕   right book quote
+    [0x3017] = "full_width_close", -- 〗  right double book quote
+    [0x3019] = "full_width_close", --     right tortoise bracket
+    [0x301B] = "full_width_close", --     right square bracket
+    [0x301E] = "full_width_close", --     double prime qm
+    [0x301F] = "full_width_close", --     low double prime qm
+    [0xFF09] = "full_width_close", -- )   right parenthesis
+    [0xFF3D] = "full_width_close", -- ]   right square brackets
+    [0xFF5D] = "full_width_close", -- }   right curve brackets
+    --
+    [0xFF62] = "half_width_open", --     left corner bracket
+    [0xFF63] = "half_width_close", --     right corner bracket
+    --
+    -- vertical opening vertical
+    --
+    -- 0xFE35, 0xFE37, 0xFE39,  0xFE3B,  0xFE3D,  0xFE3F,  0xFE41,  0xFE43,  0xFE47,
+    --
+    -- vertical closing
+    --
+    -- 0xFE36, 0xFE38, 0xFE3A,  0xFE3C,  0xFE3E,  0xFE40,  0xFE42,  0xFE44,  0xFE48,
+    --
+    -- half width opening punctuation
+    --
+    -- <empty>
+    --
+    -- full width opening punctuation
+    --
+    --  0x2236, -- ∶
+    --  0xFF0C, -- ,
+    --
+    -- half width closing punctuation_hw
+    --
+    [0x0021] = "half_width_close", -- !
+    [0x002C] = "half_width_close", -- ,
+    [0x002E] = "half_width_close", -- .
+    [0x003A] = "half_width_close", -- :
+    [0x003B] = "half_width_close", -- ;
+    [0x003F] = "half_width_close", -- ?
+    [0xFF61] = "half_width_close", -- hw full stop
+    --
+    -- full width closing punctuation
+    --
+    [0x3001] = "full_width_close", -- 、
+    [0x3002] = "full_width_close", -- 。
+    [0xFF0C] = "full_width_close", -- ,
+    [0xFF0E] = "full_width_close", --
+    --
+    -- depends on font
+    --
+    [0xFF01] = "full_width_close", -- !
+    [0xFF1F] = "full_width_close", -- ?
+    --
+    [0xFF1A] = "full_width_punct", -- :
+    [0xFF1B] = "full_width_punct", -- ;
+    --
+    -- non starter
+    --
+    [0x3005] = "non_starter", [0x3041] = "non_starter", [0x3043] = "non_starter", [0x3045] = "non_starter", [0x3047] = "non_starter",
+    [0x3049] = "non_starter", [0x3063] = "non_starter", [0x3083] = "non_starter", [0x3085] = "non_starter", [0x3087] = "non_starter",
+    [0x308E] = "non_starter", [0x3095] = "non_starter", [0x3096] = "non_starter", [0x309B] = "non_starter", [0x309C] = "non_starter",
+    [0x309D] = "non_starter", [0x309E] = "non_starter", [0x30A0] = "non_starter", [0x30A1] = "non_starter", [0x30A3] = "non_starter",
+    [0x30A5] = "non_starter", [0x30A7] = "non_starter", [0x30A9] = "non_starter", [0x30C3] = "non_starter", [0x30E3] = "non_starter",
+    [0x30E5] = "non_starter", [0x30E7] = "non_starter", [0x30EE] = "non_starter", [0x30F5] = "non_starter", [0x30F6] = "non_starter",
+    [0x30FC] = "non_starter", [0x30FD] = "non_starter", [0x30FE] = "non_starter", [0x31F0] = "non_starter", [0x31F1] = "non_starter",
+    [0x31F2] = "non_starter", [0x31F3] = "non_starter", [0x31F4] = "non_starter", [0x31F5] = "non_starter", [0x31F6] = "non_starter",
+    [0x31F7] = "non_starter", [0x31F8] = "non_starter", [0x31F9] = "non_starter", [0x31FA] = "non_starter", [0x31FB] = "non_starter",
+    [0x31FC] = "non_starter", [0x31FD] = "non_starter", [0x31FE] = "non_starter", [0x31FF] = "non_starter",
+    --
+    [0x301C] = "non_starter", [0x303B] = "non_starter", [0x303C] = "non_starter", [0x309B] = "non_starter", [0x30FB] = "non_starter",
+    [0x30FE] = "non_starter",
+    -- hyphenation
+    --
+    [0x2026] = "hyphen", -- …   ellipsis
+    [0x2014] = "hyphen", -- —   hyphen
+    --
+    [0x1361] = "ethiopic_word",
+    [0x1362] = "ethiopic_sentence",
+    --
+    -- tibetan:
+    --
+    [0x0F0B] = "breaking_tsheg",
+    [0x0F0C] = "nonbreaking_tsheg",
+
+}
+
+table.setmetatableindex(characters.scripthash, function(t,k)
+    local v
+    if not tonumber(k)                     then v = false
+    elseif (k >= 0x03040 and k <= 0x030FF)
+        or (k >= 0x031F0 and k <= 0x031FF)
+        or (k >= 0x032D0 and k <= 0x032FE)
+        or (k >= 0x0FF00 and k <= 0x0FFEF) then v = "katakana"
+    elseif (k >= 0x03400 and k <= 0x04DFF)
+        or (k >= 0x04E00 and k <= 0x09FFF)
+        or (k >= 0x0F900 and k <= 0x0FAFF)
+        or (k >= 0x20000 and k <= 0x2A6DF)
+        or (k >= 0x2F800 and k <= 0x2FA1F) then v = "chinese"
+    elseif (k >= 0x0AC00 and k <= 0x0D7A3) then v = "korean"
+    elseif (k >= 0x01100 and k <= 0x0115F) then v = "jamo_initial"
+    elseif (k >= 0x01160 and k <= 0x011A7) then v = "jamo_medial"
+    elseif (k >= 0x011A8 and k <= 0x011FF) then v = "jamo_final"
+    elseif (k >= 0x01200 and k <= 0x0139F) then v = "ethiopic_syllable"
+    elseif (k >= 0x00F00 and k <= 0x00FFF) then v = "tibetan"
+                                           else v = false
+    end
+    t[k] = v
+    return v
+end)
+
+-- storage.register("characters/scripthash", hash, "characters.scripthash")
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index f8e6a0c29..a513f273c 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.05.20 15:57}
+\newcontextversion{2021.05.21 15:02}
 
 %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 bdf95eb9d..6bdb7a44f 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2021.05.20 15:57}
+\edef\contextversion{2021.05.21 15:02}
 
 %D Kind of special:
 
diff --git a/tex/context/base/mkiv/scrp-cjk.lua b/tex/context/base/mkiv/scrp-cjk.lua
index eaffb5c5b..579c9971c 100644
--- a/tex/context/base/mkiv/scrp-cjk.lua
+++ b/tex/context/base/mkiv/scrp-cjk.lua
@@ -48,7 +48,7 @@ local userskip_code    = gluecodes.userskip
 local spaceskip_code   = gluecodes.spaceskip
 local xspaceskip_code  = gluecodes.xspaceskip
 
-local hash             = scripts.hash
+local hash             = characters.scripthash
 
 local getscriptstatus  = scripts.getstatus
 local getscriptdata    = scripts.getdata
diff --git a/tex/context/base/mkiv/scrp-ini.lua b/tex/context/base/mkiv/scrp-ini.lua
index 1ae1e6cbd..60282ae11 100644
--- a/tex/context/base/mkiv/scrp-ini.lua
+++ b/tex/context/base/mkiv/scrp-ini.lua
@@ -71,9 +71,6 @@ local new_penalty      = nodepool.penalty
 scripts                = scripts or { }
 local scripts          = scripts
 
-scripts.hash           = scripts.hash or { }
-local hash             = scripts.hash
-
 local handlers         = allocate()
 scripts.handlers       = handlers
 
@@ -139,165 +136,11 @@ local insertnodebefore, insertnodeafter  do
 
 end
 
-local hash = { -- we could put these presets in char-def.lua
-    --
-    -- half width opening parenthesis
-    --
-    [0x0028] = "half_width_open",
-    [0x005B] = "half_width_open",
-    [0x007B] = "half_width_open",
-    [0x2018] = "half_width_open", -- ‘
-    [0x201C] = "half_width_open", -- “
-    --
-    -- full width opening parenthesis
-    --
-    [0x3008] = "full_width_open", -- 〈   Left book quote
-    [0x300A] = "full_width_open", -- 《   Left double book quote
-    [0x300C] = "full_width_open", -- 「   left quote
-    [0x300E] = "full_width_open", -- 『   left double quote
-    [0x3010] = "full_width_open", -- 【   left double book quote
-    [0x3014] = "full_width_open", -- 〔   left book quote
-    [0x3016] = "full_width_open", --〖   left double book quote
-    [0x3018] = "full_width_open", --     left tortoise bracket
-    [0x301A] = "full_width_open", --     left square bracket
-    [0x301D] = "full_width_open", --     reverse double prime qm
-    [0xFF08] = "full_width_open", -- (   left parenthesis
-    [0xFF3B] = "full_width_open", -- [   left square brackets
-    [0xFF5B] = "full_width_open", -- {   left curve bracket
-    --
-    -- half width closing parenthesis
-    --
-    [0x0029] = "half_width_close",
-    [0x005D] = "half_width_close",
-    [0x007D] = "half_width_close",
-    [0x2019] = "half_width_close", -- ’   right quote, right
-    [0x201D] = "half_width_close", -- ”   right double quote
-    --
-    -- full width closing parenthesis
-    --
-    [0x3009] = "full_width_close", -- 〉   book quote
-    [0x300B] = "full_width_close", -- 》   double book quote
-    [0x300D] = "full_width_close", -- 」   right quote, right
-    [0x300F] = "full_width_close", -- 』   right double quote
-    [0x3011] = "full_width_close", -- 】   right double book quote
-    [0x3015] = "full_width_close", -- 〕   right book quote
-    [0x3017] = "full_width_close", -- 〗  right double book quote
-    [0x3019] = "full_width_close", --     right tortoise bracket
-    [0x301B] = "full_width_close", --     right square bracket
-    [0x301E] = "full_width_close", --     double prime qm
-    [0x301F] = "full_width_close", --     low double prime qm
-    [0xFF09] = "full_width_close", -- )   right parenthesis
-    [0xFF3D] = "full_width_close", -- ]   right square brackets
-    [0xFF5D] = "full_width_close", -- }   right curve brackets
-    --
-    [0xFF62] = "half_width_open", --     left corner bracket
-    [0xFF63] = "half_width_close", --     right corner bracket
-    --
-    -- vertical opening vertical
-    --
-    -- 0xFE35, 0xFE37, 0xFE39,  0xFE3B,  0xFE3D,  0xFE3F,  0xFE41,  0xFE43,  0xFE47,
-    --
-    -- vertical closing
-    --
-    -- 0xFE36, 0xFE38, 0xFE3A,  0xFE3C,  0xFE3E,  0xFE40,  0xFE42,  0xFE44,  0xFE48,
-    --
-    -- half width opening punctuation
-    --
-    -- <empty>
-    --
-    -- full width opening punctuation
-    --
-    --  0x2236, -- ∶
-    --  0xFF0C, -- ,
-    --
-    -- half width closing punctuation_hw
-    --
-    [0x0021] = "half_width_close", -- !
-    [0x002C] = "half_width_close", -- ,
-    [0x002E] = "half_width_close", -- .
-    [0x003A] = "half_width_close", -- :
-    [0x003B] = "half_width_close", -- ;
-    [0x003F] = "half_width_close", -- ?
-    [0xFF61] = "half_width_close", -- hw full stop
-    --
-    -- full width closing punctuation
-    --
-    [0x3001] = "full_width_close", -- 、
-    [0x3002] = "full_width_close", -- 。
-    [0xFF0C] = "full_width_close", -- ,
-    [0xFF0E] = "full_width_close", --
-    --
-    -- depends on font
-    --
-    [0xFF01] = "full_width_close", -- !
-    [0xFF1F] = "full_width_close", -- ?
-    --
-    [0xFF1A] = "full_width_punct", -- :
-    [0xFF1B] = "full_width_punct", -- ;
-    --
-    -- non starter
-    --
-    [0x3005] = "non_starter", [0x3041] = "non_starter", [0x3043] = "non_starter", [0x3045] = "non_starter", [0x3047] = "non_starter",
-    [0x3049] = "non_starter", [0x3063] = "non_starter", [0x3083] = "non_starter", [0x3085] = "non_starter", [0x3087] = "non_starter",
-    [0x308E] = "non_starter", [0x3095] = "non_starter", [0x3096] = "non_starter", [0x309B] = "non_starter", [0x309C] = "non_starter",
-    [0x309D] = "non_starter", [0x309E] = "non_starter", [0x30A0] = "non_starter", [0x30A1] = "non_starter", [0x30A3] = "non_starter",
-    [0x30A5] = "non_starter", [0x30A7] = "non_starter", [0x30A9] = "non_starter", [0x30C3] = "non_starter", [0x30E3] = "non_starter",
-    [0x30E5] = "non_starter", [0x30E7] = "non_starter", [0x30EE] = "non_starter", [0x30F5] = "non_starter", [0x30F6] = "non_starter",
-    [0x30FC] = "non_starter", [0x30FD] = "non_starter", [0x30FE] = "non_starter", [0x31F0] = "non_starter", [0x31F1] = "non_starter",
-    [0x31F2] = "non_starter", [0x31F3] = "non_starter", [0x31F4] = "non_starter", [0x31F5] = "non_starter", [0x31F6] = "non_starter",
-    [0x31F7] = "non_starter", [0x31F8] = "non_starter", [0x31F9] = "non_starter", [0x31FA] = "non_starter", [0x31FB] = "non_starter",
-    [0x31FC] = "non_starter", [0x31FD] = "non_starter", [0x31FE] = "non_starter", [0x31FF] = "non_starter",
-    --
-    [0x301C] = "non_starter", [0x303B] = "non_starter", [0x303C] = "non_starter", [0x309B] = "non_starter", [0x30FB] = "non_starter",
-    [0x30FE] = "non_starter",
-    -- hyphenation
-    --
-    [0x2026] = "hyphen", -- …   ellipsis
-    [0x2014] = "hyphen", -- —   hyphen
-    --
-    [0x1361] = "ethiopic_word",
-    [0x1362] = "ethiopic_sentence",
-    --
-    -- tibetan:
-    --
-    [0x0F0B] = "breaking_tsheg",
-    [0x0F0C] = "nonbreaking_tsheg",
-
-}
-
-local function provide(t,k)
-    local v
-    if not tonumber(k)                     then v = false
-    elseif (k >= 0x03040 and k <= 0x030FF)
-        or (k >= 0x031F0 and k <= 0x031FF)
-        or (k >= 0x032D0 and k <= 0x032FE)
-        or (k >= 0x0FF00 and k <= 0x0FFEF) then v = "katakana"
-    elseif (k >= 0x03400 and k <= 0x04DFF)
-        or (k >= 0x04E00 and k <= 0x09FFF)
-        or (k >= 0x0F900 and k <= 0x0FAFF)
-        or (k >= 0x20000 and k <= 0x2A6DF)
-        or (k >= 0x2F800 and k <= 0x2FA1F) then v = "chinese"
-    elseif (k >= 0x0AC00 and k <= 0x0D7A3) then v = "korean"
-    elseif (k >= 0x01100 and k <= 0x0115F) then v = "jamo_initial"
-    elseif (k >= 0x01160 and k <= 0x011A7) then v = "jamo_medial"
-    elseif (k >= 0x011A8 and k <= 0x011FF) then v = "jamo_final"
-    elseif (k >= 0x01200 and k <= 0x0139F) then v = "ethiopic_syllable"
-    elseif (k >= 0x00F00 and k <= 0x00FFF) then v = "tibetan"
-                                           else v = false
-    end
-    t[k] = v
-    return v
-end
-
-setmetatableindex(hash,provide) -- should come from char-def
-
-scripts.hash = hash
+local hash = characters.scripthash
 
 local numbertodataset = allocate()
 local numbertohandler = allocate()
 
---~ storage.register("scripts/hash", hash, "scripts.hash")
-
 scripts.numbertodataset = numbertodataset
 scripts.numbertohandler = numbertohandler
 
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 9338f9832..2808e32c9 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 0cddd6377..40d298100 100644
Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ
diff --git a/tex/context/base/mkxl/char-ini.mkxl b/tex/context/base/mkxl/char-ini.mkxl
index 6965598a9..f512e02bc 100644
--- a/tex/context/base/mkxl/char-ini.mkxl
+++ b/tex/context/base/mkxl/char-ini.mkxl
@@ -17,6 +17,7 @@
 \registerctxluafile{char-map}{} % maybe we will load this someplace else
 \registerctxluafile{char-tex}{autosuffix}
 \registerctxluafile{char-ent}{}
+\registerctxluafile{char-scr}{}
 
 \unprotect
 
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 495d9ba38..b1501f5d9 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.05.20 15:57}
+\newcontextversion{2021.05.21 15:02}
 
 %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 0674d93a4..208848803 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.05.20 15:57}
+\immutable\edef\contextversion{2021.05.21 15:02}
 
 %overloadmode 1 % check frozen / warning
 %overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/scrp-ini.lmt b/tex/context/base/mkxl/scrp-ini.lmt
index c0a42720a..138251172 100644
--- a/tex/context/base/mkxl/scrp-ini.lmt
+++ b/tex/context/base/mkxl/scrp-ini.lmt
@@ -73,9 +73,6 @@ local new_penalty       = nodepool.penalty
 scripts                 = scripts or { }
 local scripts           = scripts
 
-scripts.hash            = scripts.hash or { }
-local hash              = scripts.hash
-
 local handlers          = allocate()
 scripts.handlers        = handlers
 
@@ -111,165 +108,11 @@ local insertnodebefore, insertnodeafter  do
 
 end
 
-local hash = { -- we could put these presets in char-def.lua
-    --
-    -- half width opening parenthesis
-    --
-    [0x0028] = "half_width_open",
-    [0x005B] = "half_width_open",
-    [0x007B] = "half_width_open",
-    [0x2018] = "half_width_open", -- ‘
-    [0x201C] = "half_width_open", -- “
-    --
-    -- full width opening parenthesis
-    --
-    [0x3008] = "full_width_open", -- 〈   Left book quote
-    [0x300A] = "full_width_open", -- 《   Left double book quote
-    [0x300C] = "full_width_open", -- 「   left quote
-    [0x300E] = "full_width_open", -- 『   left double quote
-    [0x3010] = "full_width_open", -- 【   left double book quote
-    [0x3014] = "full_width_open", -- 〔   left book quote
-    [0x3016] = "full_width_open", --〖   left double book quote
-    [0x3018] = "full_width_open", --     left tortoise bracket
-    [0x301A] = "full_width_open", --     left square bracket
-    [0x301D] = "full_width_open", --     reverse double prime qm
-    [0xFF08] = "full_width_open", -- (   left parenthesis
-    [0xFF3B] = "full_width_open", -- [   left square brackets
-    [0xFF5B] = "full_width_open", -- {   left curve bracket
-    --
-    -- half width closing parenthesis
-    --
-    [0x0029] = "half_width_close",
-    [0x005D] = "half_width_close",
-    [0x007D] = "half_width_close",
-    [0x2019] = "half_width_close", -- ’   right quote, right
-    [0x201D] = "half_width_close", -- ”   right double quote
-    --
-    -- full width closing parenthesis
-    --
-    [0x3009] = "full_width_close", -- 〉   book quote
-    [0x300B] = "full_width_close", -- 》   double book quote
-    [0x300D] = "full_width_close", -- 」   right quote, right
-    [0x300F] = "full_width_close", -- 』   right double quote
-    [0x3011] = "full_width_close", -- 】   right double book quote
-    [0x3015] = "full_width_close", -- 〕   right book quote
-    [0x3017] = "full_width_close", -- 〗  right double book quote
-    [0x3019] = "full_width_close", --     right tortoise bracket
-    [0x301B] = "full_width_close", --     right square bracket
-    [0x301E] = "full_width_close", --     double prime qm
-    [0x301F] = "full_width_close", --     low double prime qm
-    [0xFF09] = "full_width_close", -- )   right parenthesis
-    [0xFF3D] = "full_width_close", -- ]   right square brackets
-    [0xFF5D] = "full_width_close", -- }   right curve brackets
-    --
-    [0xFF62] = "half_width_open", --     left corner bracket
-    [0xFF63] = "half_width_close", --     right corner bracket
-    --
-    -- vertical opening vertical
-    --
-    -- 0xFE35, 0xFE37, 0xFE39,  0xFE3B,  0xFE3D,  0xFE3F,  0xFE41,  0xFE43,  0xFE47,
-    --
-    -- vertical closing
-    --
-    -- 0xFE36, 0xFE38, 0xFE3A,  0xFE3C,  0xFE3E,  0xFE40,  0xFE42,  0xFE44,  0xFE48,
-    --
-    -- half width opening punctuation
-    --
-    -- <empty>
-    --
-    -- full width opening punctuation
-    --
-    --  0x2236, -- ∶
-    --  0xFF0C, -- ,
-    --
-    -- half width closing punctuation_hw
-    --
-    [0x0021] = "half_width_close", -- !
-    [0x002C] = "half_width_close", -- ,
-    [0x002E] = "half_width_close", -- .
-    [0x003A] = "half_width_close", -- :
-    [0x003B] = "half_width_close", -- ;
-    [0x003F] = "half_width_close", -- ?
-    [0xFF61] = "half_width_close", -- hw full stop
-    --
-    -- full width closing punctuation
-    --
-    [0x3001] = "full_width_close", -- 、
-    [0x3002] = "full_width_close", -- 。
-    [0xFF0C] = "full_width_close", -- ,
-    [0xFF0E] = "full_width_close", --
-    --
-    -- depends on font
-    --
-    [0xFF01] = "full_width_close", -- !
-    [0xFF1F] = "full_width_close", -- ?
-    --
-    [0xFF1A] = "full_width_punct", -- :
-    [0xFF1B] = "full_width_punct", -- ;
-    --
-    -- non starter
-    --
-    [0x3005] = "non_starter", [0x3041] = "non_starter", [0x3043] = "non_starter", [0x3045] = "non_starter", [0x3047] = "non_starter",
-    [0x3049] = "non_starter", [0x3063] = "non_starter", [0x3083] = "non_starter", [0x3085] = "non_starter", [0x3087] = "non_starter",
-    [0x308E] = "non_starter", [0x3095] = "non_starter", [0x3096] = "non_starter", [0x309B] = "non_starter", [0x309C] = "non_starter",
-    [0x309D] = "non_starter", [0x309E] = "non_starter", [0x30A0] = "non_starter", [0x30A1] = "non_starter", [0x30A3] = "non_starter",
-    [0x30A5] = "non_starter", [0x30A7] = "non_starter", [0x30A9] = "non_starter", [0x30C3] = "non_starter", [0x30E3] = "non_starter",
-    [0x30E5] = "non_starter", [0x30E7] = "non_starter", [0x30EE] = "non_starter", [0x30F5] = "non_starter", [0x30F6] = "non_starter",
-    [0x30FC] = "non_starter", [0x30FD] = "non_starter", [0x30FE] = "non_starter", [0x31F0] = "non_starter", [0x31F1] = "non_starter",
-    [0x31F2] = "non_starter", [0x31F3] = "non_starter", [0x31F4] = "non_starter", [0x31F5] = "non_starter", [0x31F6] = "non_starter",
-    [0x31F7] = "non_starter", [0x31F8] = "non_starter", [0x31F9] = "non_starter", [0x31FA] = "non_starter", [0x31FB] = "non_starter",
-    [0x31FC] = "non_starter", [0x31FD] = "non_starter", [0x31FE] = "non_starter", [0x31FF] = "non_starter",
-    --
-    [0x301C] = "non_starter", [0x303B] = "non_starter", [0x303C] = "non_starter", [0x309B] = "non_starter", [0x30FB] = "non_starter",
-    [0x30FE] = "non_starter",
-    -- hyphenation
-    --
-    [0x2026] = "hyphen", -- …   ellipsis
-    [0x2014] = "hyphen", -- —   hyphen
-    --
-    [0x1361] = "ethiopic_word",
-    [0x1362] = "ethiopic_sentence",
-    --
-    -- tibetan:
-    --
-    [0x0F0B] = "breaking_tsheg",
-    [0x0F0C] = "nonbreaking_tsheg",
-
-}
-
-local function provide(t,k)
-    local v
-    if not tonumber(k)                     then v = false
-    elseif (k >= 0x03040 and k <= 0x030FF)
-        or (k >= 0x031F0 and k <= 0x031FF)
-        or (k >= 0x032D0 and k <= 0x032FE)
-        or (k >= 0x0FF00 and k <= 0x0FFEF) then v = "katakana"
-    elseif (k >= 0x03400 and k <= 0x04DFF)
-        or (k >= 0x04E00 and k <= 0x09FFF)
-        or (k >= 0x0F900 and k <= 0x0FAFF)
-        or (k >= 0x20000 and k <= 0x2A6DF)
-        or (k >= 0x2F800 and k <= 0x2FA1F) then v = "chinese"
-    elseif (k >= 0x0AC00 and k <= 0x0D7A3) then v = "korean"
-    elseif (k >= 0x01100 and k <= 0x0115F) then v = "jamo_initial"
-    elseif (k >= 0x01160 and k <= 0x011A7) then v = "jamo_medial"
-    elseif (k >= 0x011A8 and k <= 0x011FF) then v = "jamo_final"
-    elseif (k >= 0x01200 and k <= 0x0139F) then v = "ethiopic_syllable"
-    elseif (k >= 0x00F00 and k <= 0x00FFF) then v = "tibetan"
-                                           else v = false
-    end
-    t[k] = v
-    return v
-end
-
-setmetatableindex(hash,provide) -- should come from char-def
-
-scripts.hash = hash
+local hash = characters.scripthash
 
 local numbertodataset = allocate()
 local numbertohandler = allocate()
 
---~ storage.register("scripts/hash", hash, "scripts.hash")
-
 scripts.numbertodataset = numbertodataset
 scripts.numbertohandler = numbertohandler
 
diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml
index 5915aef11..011f03598 100644
--- a/tex/context/interface/mkii/keys-en.xml
+++ b/tex/context/interface/mkii/keys-en.xml
@@ -144,6 +144,7 @@
 		<cd:variable name='chemistry' value='chemistry'/>
 		<cd:variable name='cite' value='cite'/>
 		<cd:variable name='closed' value='closed'/>
+		<cd:variable name='collapsed' value='collapsed'/>
 		<cd:variable name='color' value='color'/>
 		<cd:variable name='column' value='column'/>
 		<cd:variable name='columns' value='columns'/>
@@ -395,6 +396,7 @@
 		<cd:variable name='nostopper' value='nostopper'/>
 		<cd:variable name='not' value='not'/>
 		<cd:variable name='notation' value='notation'/>
+		<cd:variable name='notcollapsed' value='notcollapsed'/>
 		<cd:variable name='note' value='note'/>
 		<cd:variable name='nothanging' value='nothanging'/>
 		<cd:variable name='nothyphenated' value='nothyphenated'/>
diff --git a/tex/context/modules/mkxl/m-mathfun.mkxl b/tex/context/modules/mkxl/m-mathfun.mkxl
new file mode 100644
index 000000000..581f50971
--- /dev/null
+++ b/tex/context/modules/mkxl/m-mathfun.mkxl
@@ -0,0 +1,231 @@
+%D \module
+%D   [       file=m-mathfun,
+%D        version=2021.02.20,
+%D          title=\CONTEXT\ Extra Modules,
+%D       subtitle=Wried Math Stuff,
+%D         author=Hans Hagen,
+%D           date=\currentdate,
+%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Occasionaly some experiment results in some weird feature. It doesn't make sense
+%D to make this core functionality but if also makes no sense to throw it away. By
+%D making it a module the user can decide. It's actually an example of abusing a
+%D \LUA\ interfacing mechanism that is meant for something else.
+
+\ifdefined\compute \else
+    \permanent\protected\def\compute{\thewithproperty\plusone}
+\fi
+
+%D At some point this will move to \type {m-mathfun.lmt}:
+
+\startluacode
+    local type, load = type, load
+    local gmatch = string.gmatch
+
+    local xmath         = xmath
+    local xcomplex      = xcomplex
+    local xdecimal      = xdecimal
+
+    local context       = context
+    local ctx_mfunction = context.mfunction
+
+    local scanoptional  = tokens.scanners.optional
+    local scanargument  = tokens.scanners.argument
+
+    local createtoken   = tokens.create
+    local defined       = tokens.defined
+
+    local implement     = interfaces.implement
+
+    local compute_code  = 1
+
+    local function smart(what,name,kind)
+        if what == "value" or what == compute_code then
+            local temp = scanoptional()
+            if temp and temp ~= "" then
+                temp = "%" .. temp
+            else
+                temp = "%.6N"
+            end
+            if kind == "constant" then
+                context(temp,math[name])
+            else
+                local code = scanargument()
+                local func = load("return "..name.."("..code..")","mathfunction","t",math)
+                if type(func) == "function" then
+                    context(temp,func())
+                else
+                    context(code)
+                end
+            end
+        elseif kind == "constant" then
+          -- context[name]() -- recursion
+            name = "normal"..name
+            if defined(name) then
+                context(createtoken(name))
+            else
+                context(name)
+            end
+        else
+            ctx_mfunction(name)
+        end
+    end
+
+    local template = { name = false, usage = "value", public = true, protected = true, actions = false, overload = true }
+
+    local function install(str,kind)
+        for name in gmatch(str,"[^ ,]+") do
+            template.name    = name
+            template.actions = function(what) smart(what,name,kind) end
+            implement(template)
+        end
+    end
+
+    local function mathexpr()
+        local temp = scanoptional()
+        local code = scanargument()
+        local func = load("return " .. code,"mathexpr","t",xmath)
+        if type(func) == "function" then
+            if temp and temp ~= "" then
+                temp = "%" .. temp
+            else
+                temp = "%.6N"
+            end
+            context(temp,func())
+        else
+            context(code)
+        end
+    end
+
+    local tostring    = xdecimal.tostring
+    local toengstring = xdecimal.toengstring -- todo
+
+    local function decimalexpr()
+        local temp = scanoptional()
+        local code = scanargument()
+        local func = load("return " .. code,"decimalexpr","t",xdecimal)
+        if type(func) == "function" then
+            local result = tostring(func())
+            if temp and temp ~= "" then
+                context("%"..temp,result)
+            else
+                context(result)
+            end
+        else
+            context(code)
+        end
+    end
+
+    local topair = xcomplex.topair
+
+    local function complexexpr()
+        local temp = scanoptional()
+        local code = scanargument()
+        local func = load("return " .. code,"complexexpr","t",xcomplex)
+        if type(func) == "function" then
+         -- local result = tostring(func())
+         -- if temp and temp ~= "" then
+         --     context("%"..temp,result)
+         -- else
+         --     context(result)
+         -- end
+            if temp and temp ~= "" then
+                temp = "%" .. temp
+            else
+                temp = "%.6N + %.6Ni"
+            end
+            local result = func()
+            context(temp,topair(result))
+        else
+            context(code)
+        end
+    end
+
+    implement {
+        name      = "registermathfunction",
+        public    = true,
+        protected = true,
+        actions   = install,
+        arguments = { "optional", "optional" },
+    }
+
+    implement {
+        name    = "mathexpr",
+        public  = true,
+        actions = mathexpr,
+    }
+
+    implement {
+        name    = "decimalexpr",
+        public  = true,
+        actions = decimalexpr,
+    }
+
+    implement {
+        name    = "complexexpr",
+        public  = true,
+        actions = complexexpr,
+    }
+
+ -- install("sind cosd tand sin cos tan")
+ -- install("sqrt")
+\stopluacode
+
+\pushoverloadmode
+
+    \ifdefined\normalpi \else\let\normalpi\pi \fi
+
+    \registermathfunction[sind,cosd,tand,sin,cos,tan]
+    \registermathfunction[sqrt]
+    \registermathfunction[pi][constant]
+
+\popoverloadmode
+
+\continueifinputfile{m-mathfun.mkxl}
+
+% \pushoverloadmode
+% \let\normalpi\pi
+% \registermathfunction[sind,cosd,tand,sin,cos,tan]
+% \registermathfunction[sqrt]
+% \registermathfunction[pi][constant]
+% \popoverloadmode
+
+\usemodule[scite] \setupbodyfont[dejavu] \setuplayout[tight] \setuppapersize[A5]
+
+\starttext
+
+\startbuffer
+$ \sin (x) = \luaexpr       {math.sin(math.pi/2)} $
+$ \sin (x) = \luaexpr [.4N] {math.sin(math.pi/2)} $
+$ \sin (x) = \the\sin                     {pi/2}  $
+$ \sind(x) = \luaexpr [.4N] {math.sind(120)}      $
+$ \sind(x) = \the\sind[.4N]           {120}       $
+$ \sqrt(x) = \luaexpr       {math.sqrt(2)}        $
+$ \sqrt(x) = \luaexpr [.6N] {math.sqrt(2)}        $
+$ \sqrt(x) = \the\sqrt                {2}         $
+$ \sqrt(x) = \the\sqrt[.3N]           {2}         $
+$ \sqrt(x) = \compute\sqrt[.3N]       {2}         $
+$ \sind(x) = \luaexpr [.4N] {math.pi}             $
+$ \pi = \compute\pi[.4N]                          $
+$ \pi = \mathexpr[.40N]{pi}                       $
+$ \pi = \mathexpr[.80N]{sqrt(11)}                 $
+$ \pi = \decimalexpr[.80N]{sqrt(11)}              $
+$ \pi = \decimalexpr{sqrt(11)}                    $
+$ c = \complexexpr{123 + new(456,789)}            $
+\stopbuffer
+
+Take your choice:
+
+\typebuffer[option=TEX]
+
+And get:
+
+\startlines
+    \getbuffer
+\stoplines
+
+\stoptext
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 59cbd9ef8..b839fa3db 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-05-20 15:57
+-- merge date  : 2021-05-21 15:02
 
 do -- begin closure to overcome local limits and interference
 
-- 
cgit v1.2.3