From 9f36318b0e571bcbc93dc2112d01bbf2178ed020 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Wed, 10 Oct 2018 21:09:32 +0200
Subject: 2018-10-08 17:52:00

---
 tex/context/base/mkii/cont-new.mkii                |   2 +-
 tex/context/base/mkii/context.mkii                 |   2 +-
 tex/context/base/mkii/mult-de.mkii                 |   1 +
 tex/context/base/mkii/mult-en.mkii                 |   1 +
 tex/context/base/mkiv/back-exp.lua                 |   6 +-
 tex/context/base/mkiv/back-swf.mkiv                | 101 +---
 tex/context/base/mkiv/cont-new.mkiv                |   4 +-
 tex/context/base/mkiv/context.mkiv                 |   2 +-
 tex/context/base/mkiv/font-cff.lua                 |   2 +-
 tex/context/base/mkiv/font-one.lua                 |   1 +
 tex/context/base/mkiv/font-oup.lua                 |  57 +-
 tex/context/base/mkiv/grph-inc.mkiv                |   2 +-
 tex/context/base/mkiv/java-imp-exa.mkiv            | 395 -------------
 tex/context/base/mkiv/java-imp-example.mkiv        | 398 +++++++++++++
 tex/context/base/mkiv/java-imp-fields.mkiv         | 648 +++++++++++++++++++++
 tex/context/base/mkiv/java-imp-fil.mkiv            |  52 --
 tex/context/base/mkiv/java-imp-fld.mkiv            | 648 ---------------------
 tex/context/base/mkiv/java-imp-highlight.mkiv      |  34 ++
 tex/context/base/mkiv/java-imp-print.mkiv          |  52 ++
 tex/context/base/mkiv/java-imp-rhh.mkiv            |  34 --
 tex/context/base/mkiv/java-imp-steps.mkiv          | 123 ++++
 tex/context/base/mkiv/java-imp-stp.mkiv            | 123 ----
 tex/context/base/mkiv/java-imp-videoplayer.mkiv    |  82 +++
 tex/context/base/mkiv/java-imp-vplayer.mkiv        | 105 ++++
 tex/context/base/mkiv/java-ini.mkiv                |   9 +-
 tex/context/base/mkiv/lang-dis.lua                 |   3 +-
 tex/context/base/mkiv/lang-mis.mkiv                |   6 +-
 tex/context/base/mkiv/lpdf-pde.lua                 |  14 +-
 tex/context/base/mkiv/lpdf-swf.lua                 |   6 +-
 tex/context/base/mkiv/lpdf-wid.lua                 |   7 +-
 tex/context/base/mkiv/math-ini.lua                 |   7 -
 tex/context/base/mkiv/pack-mrl.mkiv                |  87 +--
 tex/context/base/mkiv/page-sid.mkiv                |  17 +-
 tex/context/base/mkiv/status-files.pdf             | Bin 26068 -> 26105 bytes
 tex/context/base/mkiv/status-lua.pdf               | Bin 269399 -> 269460 bytes
 tex/context/base/mkiv/strc-ref.lua                 |  26 +-
 tex/context/base/mkiv/symb-imp-fontawesome.mkiv    |  33 +-
 tex/context/base/mkiv/tabl-ntb.mkiv                |  76 +--
 tex/context/base/mkiv/trac-log.lua                 |   9 +
 tex/context/base/mkiv/util-sql-imp-sqlite.lua      |  13 +-
 tex/context/fonts/mkiv/type-imp-plex.mkiv          | 227 ++++++--
 tex/context/interface/mkii/keys-de.xml             |   1 +
 tex/context/interface/mkii/keys-en.xml             |   1 +
 tex/context/interface/mkiv/context-en.xml          |   4 +-
 tex/context/interface/mkiv/i-context.pdf           | Bin 857465 -> 857333 bytes
 tex/context/interface/mkiv/i-floats.xml            |   4 +-
 tex/context/interface/mkiv/i-readme.pdf            | Bin 60771 -> 60774 bytes
 tex/context/modules/mkiv/m-matrix.mkiv             | 153 ++++-
 tex/context/modules/mkiv/s-fonts-system.lua        | 144 ++++-
 tex/context/modules/mkiv/s-fonts-system.mkiv       |  13 +-
 tex/generic/context/luatex/luatex-fonts-merged.lua |  32 +-
 51 files changed, 2206 insertions(+), 1561 deletions(-)
 delete mode 100644 tex/context/base/mkiv/java-imp-exa.mkiv
 create mode 100644 tex/context/base/mkiv/java-imp-example.mkiv
 create mode 100644 tex/context/base/mkiv/java-imp-fields.mkiv
 delete mode 100644 tex/context/base/mkiv/java-imp-fil.mkiv
 delete mode 100644 tex/context/base/mkiv/java-imp-fld.mkiv
 create mode 100644 tex/context/base/mkiv/java-imp-highlight.mkiv
 create mode 100644 tex/context/base/mkiv/java-imp-print.mkiv
 delete mode 100644 tex/context/base/mkiv/java-imp-rhh.mkiv
 create mode 100644 tex/context/base/mkiv/java-imp-steps.mkiv
 delete mode 100644 tex/context/base/mkiv/java-imp-stp.mkiv
 create mode 100644 tex/context/base/mkiv/java-imp-videoplayer.mkiv
 create mode 100644 tex/context/base/mkiv/java-imp-vplayer.mkiv

(limited to 'tex')

diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 269f053f9..439cdf147 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{2018.10.03 16:02}
+\newcontextversion{2018.10.08 17:44}
 
 %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 5fa5ed7d2..88a4cac8c 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{2018.10.03 16:02}
+\edef\contextversion{2018.10.08 17:44}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii
index 6e30e12ad..0958b3464 100644
--- a/tex/context/base/mkii/mult-de.mkii
+++ b/tex/context/base/mkii/mult-de.mkii
@@ -1241,6 +1241,7 @@
 \setinterfaceconstant{textstyle}{textstil}
 \setinterfaceconstant{textwidth}{textbreite}
 \setinterfaceconstant{threshold}{threshold}
+\setinterfaceconstant{time}{time}
 \setinterfaceconstant{title}{titel}
 \setinterfaceconstant{titlecolor}{titelfarbe}
 \setinterfaceconstant{titlecommand}{titlecommand}
diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii
index a9fffa0ea..bbe977f64 100644
--- a/tex/context/base/mkii/mult-en.mkii
+++ b/tex/context/base/mkii/mult-en.mkii
@@ -1241,6 +1241,7 @@
 \setinterfaceconstant{textstyle}{textstyle}
 \setinterfaceconstant{textwidth}{textwidth}
 \setinterfaceconstant{threshold}{threshold}
+\setinterfaceconstant{time}{time}
 \setinterfaceconstant{title}{title}
 \setinterfaceconstant{titlecolor}{titlecolor}
 \setinterfaceconstant{titlecommand}{titlecommand}
diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua
index 10aca0a46..04f376d96 100644
--- a/tex/context/base/mkiv/back-exp.lua
+++ b/tex/context/base/mkiv/back-exp.lua
@@ -2950,6 +2950,7 @@ local collectresults  do -- too many locals otherwise
         local p
         local localparagraph
         local maybewrong
+        local pid
         for n, id, subtype in nextnode, head do
             if trace_detail then
                 showdetail(n,id,subtype)
@@ -3180,6 +3181,8 @@ end
                             if not keephyphens then
                                 nofcurrentcontent = nofcurrentcontent - 1
                             end
+                        elseif pid == disc_code then
+                            -- go on .. tricky: we should mark the glyhs as coming from a disc
                         elseif not somespace[r] then
                             local a = getattr(n,a_tagged) or pat
                             if a == last then
@@ -3288,7 +3291,8 @@ end
             elseif id == localpar_code then
                 localparagraph = getattr(n,a_taggedpar)
             end
-            p = n
+            p   = n
+            pid = id
         end
         if maybewrong then
             showmaybe(maybewrong)
diff --git a/tex/context/base/mkiv/back-swf.mkiv b/tex/context/base/mkiv/back-swf.mkiv
index 0a53a8fd2..20a94266a 100644
--- a/tex/context/base/mkiv/back-swf.mkiv
+++ b/tex/context/base/mkiv/back-swf.mkiv
@@ -11,6 +11,9 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
+%D The question is: should I still document this in interaction.tex or just
+%D assume it's obsolete technology \unknown
+
 %D This is only a placeholder that demonstrates the usage of swf resources.
 %D There is no need to include this file into the format. The module was
 %D tested by Luigi and Willi and based on their suggestions the functionality
@@ -58,6 +61,8 @@
 %D   [file=test.mp4,
 %D    label=foo]
 %D
+%D \useJSscripts[vplayer] % or \useJSscripts[videoplayer]
+%D
 %D \goto{START} [JS(StartShockwave{foo})]
 %D \goto{REWIND}[JS(RewindShockwave{foo})]
 %D \goto{PAUSE} [JS(PauseShockwave{foo})]
@@ -84,100 +89,8 @@
 
 \unprotect
 
-\startluaparameterset[shockwave:display]
-    toolbar  = true,
- -- preview  = "somefile",
-    open     = "click",
-    close    = "focus",
-\stopluaparameterset
-
-% using vplayer9.swf from ctan:
-
-\useexternalfigure
-  [shockwave]
-  [vplayer9.swf]
-% [arguments=\luaparameterset{shockwave:arguments}{src="\externalfigureparameter\v!file",source="\externalfigureparameter\v!file"},
-  [\c!arguments=\luaparameterset{shockwave:arguments}{source="\externalfigureparameter\v!file",autoPlay=true},
-   \c!resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}},
-   \c!display=shockwave:display]
-
-\startJSpreamble shockwave used now
-    function StartShockwave(label) {
-        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
-        if (rm.activated) {
-            // ok
-        } else {
-            rm.activated = true ;
-        }
-        rm.callAS("rewind") ;
-        rm.callAS("playPause") ;
-    }
-    function StopShockwave(label) {
-        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
-        if (rm.activated) {
-            rm.callAS("pause") ;
-            rm.callAS("rewind") ;
-        }
-    }
-    function RewindShockwave(label) {
-        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
-        if (rm.activated) {
-            rm.callAS("rewind") ;
-        }
-    }
-    function PauseShockwave(label) {
-        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
-        if (rm.activated) {
-            rm.callAS("playPause") ;
-        }
-    }
-\stopJSpreamble
-
-% using videoplayer.swf from adobe or strobemediaplayback.swf from sourceforge:
-
-%\useexternalfigure
-%  [shockwave]
-%  [videoplayer.swf]
-%  [\c!arguments=\luaparameterset{shockwave:arguments}{source="\externalfigureparameter\v!file"},
-%   \c!resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}},
-%   \c!display=shockwave:display]
-
-\startJSpreamble shockwave used now
-    function StartShockwave(label) {
-        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
-        if (rm.activated) {
-            rm.callAS("multimedia_play") ;
-        } else {
-            rm.activated = true ;
-        }
-    }
-    function StopShockwave(label) {
-        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
-        if (rm.activated) {
-            rm.callAS("multimedia_pause") ;
-            rm.callAS("multimedia_rewind") ;
-        }
-    }
-    function RewindShockwave(label) {
-        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
-        if (rm.activated) {
-            rm.callAS("multimedia_rewind") ;
-        }
-    }
-    function PauseShockwave(label) {
-        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
-        if (rm.activated) {
-            rm.callAS("multimedia_pause") ;
-        }
-    }
-\stopJSpreamble
-
-% \useexternalfigure
-%   [shockwave]
-%   [strobemediaplayback.swf]
-%   [arguments=\luaparameterset{shockwave:arguments}{src="\externalfigureparameter\v!file"},
-%    resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}},
-%    display=shockwave:display]
+%D The code has moved to the (explicitly loaded) \JAVASCRIPT\ modules. See there
+%D for more info.
 
 \protect \endinput
 
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 3e3ab3bde..c3c035160 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2018.10.03 16:02}
+\newcontextversion{2018.10.08 17:44}
 
 %D This file is loaded at runtime, thereby providing an excellent place for
 %D hacks, patches, extensions and new features.
@@ -30,6 +30,8 @@
     \let\w\mathword
 \to \everymathematics
 
+\let\assumelongusagecs\relax
+
 % done
 
 \protect \endinput
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 5a944df23..9b166fb03 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -42,7 +42,7 @@
 %D has to match \type {YYYY.MM.DD HH:MM} format.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2018.10.03 16:02}
+\edef\contextversion{2018.10.08 17:44}
 \edef\contextkind   {beta}
 
 %D For those who want to use this:
diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua
index ecd49fa3a..2c7d61521 100644
--- a/tex/context/base/mkiv/font-cff.lua
+++ b/tex/context/base/mkiv/font-cff.lua
@@ -28,7 +28,7 @@ if not modules then modules = { } end modules ['font-cff'] = {
 
 local next, type, tonumber = next, type, tonumber
 local byte, char, gmatch = string.byte, string.char, string.gmatch
-local concat, remove = table.concat, table.remove
+local concat, remove, unpack = table.concat, table.remove, table.unpack
 local floor, abs, round, ceil, min, max = math.floor, math.abs, math.round, math.ceil, math.min, math.max
 local P, C, R, S, C, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct
 local lpegmatch = lpeg.match
diff --git a/tex/context/base/mkiv/font-one.lua b/tex/context/base/mkiv/font-one.lua
index 85b9d406e..48bf117fe 100644
--- a/tex/context/base/mkiv/font-one.lua
+++ b/tex/context/base/mkiv/font-one.lua
@@ -106,6 +106,7 @@ function afm.load(filename)
                 afmenhancers.apply(data,filename)
              -- otfreaders.addunicodetable(data) -- only when not done yet
                 fonts.mappings.addtounicode(data,filename)
+                otfreaders.stripredundant(data)
              -- otfreaders.extend(data)
                 otfreaders.pack(data)
                 data.size = size
diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua
index 012b007d5..14df60822 100644
--- a/tex/context/base/mkiv/font-oup.lua
+++ b/tex/context/base/mkiv/font-oup.lua
@@ -715,7 +715,7 @@ local function checklookups(fontdata,missing,nofmissing)
             end
         end
         if next(done) then
-            report_unicode("not unicoded: % t",sortedkeys(done))
+            report_unicodes("not unicoded: % t",sortedkeys(done))
         end
     end
 end
@@ -916,12 +916,53 @@ local function unifyglyphs(fontdata,usenames)
     return indices, names
 end
 
-local p_bogusname = (
-    (P("uni") + P("UNI") + P("Uni") + P("U") + P("u")) * S("Xx")^0 * R("09","AF")^1
-  + (P("identity") + P("Identity") + P("IDENTITY")) * R("09","AF")^1
-  + (P("index") + P("Index") + P("INDEX")) * R("09")^1
-) * (P(-1) + P("."))
+local p_crappyname  do
+
+    local p_hex   = R("af","AF","09")
+    local p_digit = R("09")
+    local p_done  = S("._-")^0 + P(-1)
+    local p_alpha = R("az","AZ")
+    local p_ALPHA = R("AZ")
+
+    p_crappyname = (
+    -- (P("uni") + P("UNI") + P("Uni") + P("U") + P("u"))
+        lpeg.utfchartabletopattern({ "uni", "u" },true)
+      * S("Xx_")^0
+      * p_hex^1
+   -- + (P("identity") + P("Identity") + P("IDENTITY") + P("glyph") + P("jamo"))
+      + lpeg.utfchartabletopattern({ "identity", "glyph", "jamo" },true)
+      * p_hex^1
+   -- + (P("index") + P("Index") + P("INDEX")+ P("afii"))
+      + lpeg.utfchartabletopattern({ "index", "afii" }, true)
+      * p_digit^1
+      -- also happens l
+      + p_digit
+      * p_hex^3
+      + p_alpha
+      * p_digit^1
+      -- sort of special
+      + P("aj")
+      * p_digit^1
+      + P("eh_")
+      * (p_digit^1 + p_ALPHA * p_digit^1)
+      + (1-P("_"))^1
+      * P("_uni")
+      * p_hex^1
+      + P("_")
+      * P(1)^1
+    ) * p_done
 
+end
+
+-- In context we only keep glyph names because of tracing and access by name
+-- so weird names make no sense.
+
+local forcekeep = false -- only for testing something
+
+directives.register("otf.keepnames",function(v)
+    report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+    forcekeep = v
+end)
 
 local function stripredundant(fontdata)
     local descriptions = fontdata.descriptions
@@ -939,7 +980,7 @@ local function stripredundant(fontdata)
         else
             for unicode, d in next, descriptions do
                 local name = d.name
-                if name and lpegmatch(p_bogusname,name) then
+                if name and lpegmatch(p_crappyname,name) then
                     d.name = nil
                     n = n + 1
                 end
@@ -960,6 +1001,8 @@ local function stripredundant(fontdata)
     end
 end
 
+readers.stripredundant = stripredundant
+
 function readers.getcomponents(fontdata) -- handy for resolving ligatures when names are missing
     local resources = fontdata.resources
     if resources then
diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv
index 62ac39864..371725271 100644
--- a/tex/context/base/mkiv/grph-inc.mkiv
+++ b/tex/context/base/mkiv/grph-inc.mkiv
@@ -204,7 +204,7 @@
            {\grph_include_use_indeed{#1}{#2}{#3}{#4}}}}}
 
 \def\grph_include_use_indeed#1#2#3#4%
-  {\setvalue{\??externalfigureinstance#1}{\grph_include_setup{#2}{#3}{#4}}%
+  {\dodoglobal\setvalue{\??externalfigureinstance#1}{\grph_include_setup{#2}{#3}{#4}}%
    \grph_include_analyze_collection[#2][#4]}
 
 % inclusion
diff --git a/tex/context/base/mkiv/java-imp-exa.mkiv b/tex/context/base/mkiv/java-imp-exa.mkiv
deleted file mode 100644
index 584ee1351..000000000
--- a/tex/context/base/mkiv/java-imp-exa.mkiv
+++ /dev/null
@@ -1,395 +0,0 @@
-%D \module
-%D   [       file=java-exa,
-%D        version=2002.??.??,
-%D          title=\CONTEXT\ JavaScript Macros,
-%D       subtitle=Example Support,
-%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.
-
-% XFDF versus HTML
-% localhost versus remote versus set
-
-% filename | filename-nr => name
-% fakename | fakename-nr => file upload, unless localhost
-%
-% we erase the list because otherwise we end up in browser remembering
-% problems; also, it is not possible to set upload fields 'manually'
-
-\startJSpreamble request_1 used now
-
-    var example_method = "HTML" ;
-    var example_host   = "" ;
-    var example_port   = "" ;
-    var example_url    = "" ;
-    var example_file   = "" ;
-
-    var example_log    = true ; % false
-
-    function stripped_exa_value( name ) {
-        f = this.getField(name) ;
-        if (f) {
-            str = f.value ;
-            if (str.indexOf(name+'-')==0) {
-                str = str.substr(name.length+1) ;
-            }
-            return str ;
-        } else {
-            return "" ;
-        }
-    }
-
-    function identify_example_url ( ) {
-        if (example_log) {
-            console.clear ;
-            console.println("base url: "+this.baseURL) ;
-            console.println("this url: "+this.URL) ;
-        }
-        if (this.baseURL != "") {
-            example_url = this.baseURL ;
-        } else {
-            if (this.URL != "") {
-                example_url = this.URL
-            }
-        }
-        if (example_url.indexOf("file://")>=0) {
-            example_url = "" ;
-        }
-        str = stripped_exa_value("examplehost") ;
-        if (str != "auto") {
-            example_host = str ;
-            if (str == "localhost") {
-                example_port = "8061"
-            }
-        }
-        str = stripped_exa_value("exampleport") ;
-        if (str != "auto") {
-            example_port = str ;
-        }
-        if (example_log) {
-            console.println("example_url: "+example_url) ;
-            console.println("example_host: "+example_host) ;
-            console.println("example_port: "+example_port) ;
-        }
-    }
-
-    function check_example_url ( url ) {
-        if (url.indexOf("file://")>=0) {
-            url = "http://localhost:8061" ;
-            console.println("file url replaced by: "+url) ;
-        } else {
-            if (url.indexOf("://")<0) {
-                url = "http://" + url ;
-            }
-            if (example_log) {
-                console.println("url before check: "+url) ;
-            }
-%            url = url.replace(/(http:\\\/\\\/.+)(\\\/.*$)/, "$1") ;
-            url = url.replace(/(https*:\\\/\\\/.+?)(\\\/.*$)/, "$1/exarequest") ;
-            if (example_log) {
-                console.println("url after check: "+url) ;
-            }
-        }
-        return url ;
-    }
-
-    function set_example_xfdf ( method ) {
-        example_method = method ;
-    }
-
-    function set_example_file ( file ) {
-        example_method = file ;
-    }
-
-    function set_example_host ( host ) {
-        example_host = host ;
-    }
-
-    function set_example_port ( port ) {
-        example_host = host ;
-    }
-
-    function do_erase_example_file(tag) {
-        f = this.getField(tag) ;
-        if (f) {
-            f.value = "" ;
-        }
-    }
-
-    function do_erase_example_list(tag) {
-        for (i=1;i<=100;i++) {
-            f = this.getField(tag+"-"+i) ;
-            if (f) {
-                f.value = "" ;
-            } else {
-                return
-            }
-        }
-    }
-
-    function do_submit_example_url ( url ) {
-        if ((example_method == "XFDF" ) || (url.indexOf("localhost")>=0)) {
-            do_erase_example_file("fakename") ;
-            do_erase_example_list("fakename") ;
-        }
-        url = check_example_url(url) ;
-        if (example_log) {
-            console.println("submitting form to "+url+" using method "+example_method) ;
-        }
-        if (example_file != "") {
-            url = url + "/" + example_file ;
-        }
-        % we need the bFDF for acrobat 5
-        this.submitForm({cURL : url, bFDF : false, cSubmitAs : example_method}) ;
-    }
-
-    function submit_example_form ( ) {
-        identify_example_url() ;
-        if (example_host != "") {
-            if (example_port != "") {
-                do_submit_example_url(example_host+":"+example_port) ;
-            } else {
-                do_submit_example_url(example_host) ;
-            }
-        } else {
-            if (example_url != "") {
-                do_submit_example_url(example_url) ;
-            } else {
-                if (example_port != "") {
-                    do_submit_example_url("localhost"+":"+example_port) ;
-                } else {
-                    do_submit_example_url("localhost:8061") ; % local exampler
-                }
-            }
-        }
-        resetfilename () ;
-    }
-
-    function submit_form ( host, port) {
-        set_example_host(host) ;
-        set_example_post(post) ;
-        submit_example_form ;
-    }
-
-\stopJSpreamble
-
-\startJSpreamble request_2 used now
-
-    var exa_command    = "" ;
-    var exa_option     = "" ;
-    var exa_filename   = "" ;
-    var exa_filelist   = "" ;
-    var exa_registered = "" ;
-
-    function set_request (command,option) {
-        exa_command = command ;
-        if (exa_command == "") {
-            exa_option = option ;
-        } else { if (option == "") {
-            exa_option = "" ;
-        } else { if (option.indexOf("--")<0) {
-            exa_option = "--action=" + option ;
-        } else {
-            exa_option = option ;
-        } } }
-    }
-
-    function assemble_request ( ) {
-        v = this.getField('filename') ;
-        if (v) {
-            exa_filename = v.value ;
-        }
-        v = this.getField('filelist') ;
-        if (v) {
-            exa_filelist = v.value ;
-        }
-%       exa_filename = exa_filename.replace(/\\\\/g,'/') ;
-%       exa_filelist = exa_filelist.replace(/\\\\/g,'/') ;
-        str = "<?xml version='1.0' ?>\\n" ;
-        str = str+"<exa:request xmlns:exa='http://www.pragma-ade.com/schemas/example.rng'><exa:application>" ;
-        if (exa_filelist == "") {
-            exa_filelist = exa_registered ;
-        } else { if (exa_registered != "") {
-            exa_filelist = exa_filelist + "\\n" + exa_registered ;
-        } }
-        if (exa_command != "") {
-            str = str+"<exa:command>"+exa_command+"</exa:command>" ;
-        }
-        if (exa_option != "") {
-            str = str+"<exa:option>"+exa_option+"</exa:option>" ;
-        }
-        if (exa_filename != "") {
-            str = str+"<exa:filename>"+exa_filename+"</exa:filename>" ;
-        }
-        var fls = "" ;
-        if (exa_filelist != "") {
-            % old method, soon obsolete
-            lst = exa_filelist.split(/\\s/) ;
-            for (i=0;i<lst.length;i++) {
-                fls = fls+"<exa:entry>"+lst[i]+"</exa:entry>" ;
-            }
-        } else { if (exa_multiple) {
-            for (i=1;i<=100;i++) {
-                % console.println("file field "+i) ;
-                f = this.getField("filename-"+ i) ;
-%                 if (f) { if (f.value != "") {
-%                     if (g) { if (g.value == "") {
-%                         fls = fls+"<exa:entry>"+f.value+"</exa:entry>" ;
-%                     } else {
-%                         fls = fls+"<exa:entry label='" + g.value + "'>"+f.value+"</exa:entry>" ;
-%                     } } else {
-%                         fls = fls+"<exa:entry>"+f.value+"</exa:entry>" ;
-%                     }
-%                 } }
-                if (f) { if (f.value != "") {
-                    fls = fls + "<exa:entry" ;
-                    g = this.getField("dataname-"+ i) ;
-                    if (g) { if (g.value == "") {
-                        % console.println("a") ;
-                        fls = fls + ">" ;
-                    } else {
-                        % console.println("b") ;
-                        fls = fls + " label='" + g.value + "'>" ;
-                    } } else {
-                        % console.println("c") ;
-                        fls = fls + ">" ;
-                    }
-                    fls = fls + f.value + "</exa:entry>" ;
-                } }
-            }
-        } }
-        if (fls != "") {
-            str = str + "<exa:filelist>" + fls + "</exa:filelist>" ;
-        }
-        str = str + "</exa:application></exa:request>" ;
-        v = this.getField('exa:request') ;
-        if (v) {
-            v.value = str ;
-        }
-    }
-
-\stopJSpreamble
-
-\startJSpreamble request_3 used now
-
-    var exa_multiple = false ;
-
-    function setfilename ( suffixes ) {
-        if (event.targetName) {
-            var name = event.targetName ;
-            var fake = name.replace(/filename/,"fakename") ;
-        } else {
-            var name = 'filename' ;
-            var fake = 'fakename' ;
-        }
-        f = this.getField(fake) ;
-        if (f) {
-            f.browseForFileToSubmit() ;
-            if ((suffixes != "") && (f.value != "")) {
-                %
-                s = suffixes.replace(/,/g,"|") ;
-                r = new RegExp() ;
-                s = "\\\\.(" + s + ")$" ;
-                r.compile(s, "i") ;
-                if (f.value.search(r)<=0) {
-                    f.value = "" ;
-                    app.alert('This filetype is not permitted.') ;
-                %
-                % lst = suffixes.split(/,/) ;
-                % ok = false ;
-                % for (i=0;i<lst.length;i++) {
-                %     if (f.value == lst[i]) {
-                %         ok = true ;
-                %     }
-                % }
-                % if (! ok) {
-                %     f.value = "" ;
-                %     app.alert('This filetype is not permitted.') ;
-                %
-                }
-            }
-            g = this.getField(name) ;
-            if (g) {
-                g.value = f.value ;
-            }
-% we need to set the value of the selector to empty else
-% we get some funny preloading of multimeg files in spite
-% of the specs that say that xml fields will not get sent
-%             if (example_method == "XFDF" ) {
-%                 f.value = "" ;
-%             } else {
-%                 identify_example_url ;
-%                 if (example_url.indexOf("localhost")>=0) {
-%                     f.value = "" ;
-%                 }
-%             }
-        }
-        this.dirty = false ;
-    }
-
-    function addfilename () {
-        if (exa_multiple) {
-            h = this.getField("filelist") ;
-            g = this.getField("filename") ;
-            if ((g) && (h)) {
-                str = g.value ;
-                if (h.value == "") {
-                    h.value = str ;
-                } else {
-                    h.value = h.value + "\\n" + str ;
-                }
-                g.value = "" ;
-                this.value = "" ;
-            }
-        }
-        this.dirty = false ;
-    }
-
-    % this only works with client that assembles request
-
-    function registerfilename (str) {
-        if (str!="") {
-            h = this.getField("filelist") ;
-            if (h) {
-                if (h.value != "") {
-                    h.value = h.value + "\\n" ;
-                }
-                h.value = h.value + str ;
-            } else {
-                if (exa_registered != "") {
-                    exa_registered = exa_registered + "\\n" ;
-                }
-                exa_registered = exa_registered + str ;
-            }
-        }
-        console.show ;
-        console.println('registered files') ;
-        console.println("file: "+str) ;
-        console.println("list: "+exa_registered) ;
-        this.dirty = false ;
-    }
-
-    function checkfilename () {
-    }
-
-    function getfilename ( suffixes ) {
-        setfilename(suffixes) ;
-        checkfilename() ;
-        addfilename() ;
-    }
-
-    function resetfilename () {
-        do_erase_example_file("fakename") ;
-        do_erase_example_file("filename") ;
-        do_erase_example_file("filelist") ;
-        do_erase_example_list("filename") ;
-        do_erase_example_list("fakename") ;
-    }
-
-\stopJSpreamble
-
-\endinput
diff --git a/tex/context/base/mkiv/java-imp-example.mkiv b/tex/context/base/mkiv/java-imp-example.mkiv
new file mode 100644
index 000000000..82d5b0cb0
--- /dev/null
+++ b/tex/context/base/mkiv/java-imp-example.mkiv
@@ -0,0 +1,398 @@
+%D \module
+%D   [       file=java-imp-example, % was: java-exa
+%D        version=2002.??.??,
+%D          title=\CONTEXT\ JavaScript Macros,
+%D       subtitle=Example Support,
+%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 This code is just kept as an example of dealign with forms and submitting data to
+%D a server. We used this to create stepwise growing student test forms and such.
+
+% XFDF versus HTML
+% localhost versus remote versus set
+
+% filename | filename-nr => name
+% fakename | fakename-nr => file upload, unless localhost
+%
+% we erase the list because otherwise we end up in browser remembering
+% problems; also, it is not possible to set upload fields 'manually'
+
+\startJSpreamble request_1 used now
+
+    var example_method = "HTML" ;
+    var example_host   = "" ;
+    var example_port   = "" ;
+    var example_url    = "" ;
+    var example_file   = "" ;
+
+    var example_log    = true ; % false
+
+    function stripped_exa_value( name ) {
+        f = this.getField(name) ;
+        if (f) {
+            str = f.value ;
+            if (str.indexOf(name+'-')==0) {
+                str = str.substr(name.length+1) ;
+            }
+            return str ;
+        } else {
+            return "" ;
+        }
+    }
+
+    function identify_example_url ( ) {
+        if (example_log) {
+            console.clear ;
+            console.println("base url: "+this.baseURL) ;
+            console.println("this url: "+this.URL) ;
+        }
+        if (this.baseURL != "") {
+            example_url = this.baseURL ;
+        } else {
+            if (this.URL != "") {
+                example_url = this.URL
+            }
+        }
+        if (example_url.indexOf("file://")>=0) {
+            example_url = "" ;
+        }
+        str = stripped_exa_value("examplehost") ;
+        if (str != "auto") {
+            example_host = str ;
+            if (str == "localhost") {
+                example_port = "8061"
+            }
+        }
+        str = stripped_exa_value("exampleport") ;
+        if (str != "auto") {
+            example_port = str ;
+        }
+        if (example_log) {
+            console.println("example_url: "+example_url) ;
+            console.println("example_host: "+example_host) ;
+            console.println("example_port: "+example_port) ;
+        }
+    }
+
+    function check_example_url ( url ) {
+        if (url.indexOf("file://")>=0) {
+            url = "http://localhost:8061" ;
+            console.println("file url replaced by: "+url) ;
+        } else {
+            if (url.indexOf("://")<0) {
+                url = "http://" + url ;
+            }
+            if (example_log) {
+                console.println("url before check: "+url) ;
+            }
+%            url = url.replace(/(http:\\\/\\\/.+)(\\\/.*$)/, "$1") ;
+            url = url.replace(/(https*:\\\/\\\/.+?)(\\\/.*$)/, "$1/exarequest") ;
+            if (example_log) {
+                console.println("url after check: "+url) ;
+            }
+        }
+        return url ;
+    }
+
+    function set_example_xfdf ( method ) {
+        example_method = method ;
+    }
+
+    function set_example_file ( file ) {
+        example_method = file ;
+    }
+
+    function set_example_host ( host ) {
+        example_host = host ;
+    }
+
+    function set_example_port ( port ) {
+        example_host = host ;
+    }
+
+    function do_erase_example_file(tag) {
+        f = this.getField(tag) ;
+        if (f) {
+            f.value = "" ;
+        }
+    }
+
+    function do_erase_example_list(tag) {
+        for (i=1;i<=100;i++) {
+            f = this.getField(tag+"-"+i) ;
+            if (f) {
+                f.value = "" ;
+            } else {
+                return
+            }
+        }
+    }
+
+    function do_submit_example_url ( url ) {
+        if ((example_method == "XFDF" ) || (url.indexOf("localhost")>=0)) {
+            do_erase_example_file("fakename") ;
+            do_erase_example_list("fakename") ;
+        }
+        url = check_example_url(url) ;
+        if (example_log) {
+            console.println("submitting form to "+url+" using method "+example_method) ;
+        }
+        if (example_file != "") {
+            url = url + "/" + example_file ;
+        }
+        % we need the bFDF for acrobat 5
+        this.submitForm({cURL : url, bFDF : false, cSubmitAs : example_method}) ;
+    }
+
+    function submit_example_form ( ) {
+        identify_example_url() ;
+        if (example_host != "") {
+            if (example_port != "") {
+                do_submit_example_url(example_host+":"+example_port) ;
+            } else {
+                do_submit_example_url(example_host) ;
+            }
+        } else {
+            if (example_url != "") {
+                do_submit_example_url(example_url) ;
+            } else {
+                if (example_port != "") {
+                    do_submit_example_url("localhost"+":"+example_port) ;
+                } else {
+                    do_submit_example_url("localhost:8061") ; % local exampler
+                }
+            }
+        }
+        resetfilename () ;
+    }
+
+    function submit_form ( host, port) {
+        set_example_host(host) ;
+        set_example_post(post) ;
+        submit_example_form ;
+    }
+
+\stopJSpreamble
+
+\startJSpreamble request_2 used now
+
+    var exa_command    = "" ;
+    var exa_option     = "" ;
+    var exa_filename   = "" ;
+    var exa_filelist   = "" ;
+    var exa_registered = "" ;
+
+    function set_request (command,option) {
+        exa_command = command ;
+        if (exa_command == "") {
+            exa_option = option ;
+        } else { if (option == "") {
+            exa_option = "" ;
+        } else { if (option.indexOf("--")<0) {
+            exa_option = "--action=" + option ;
+        } else {
+            exa_option = option ;
+        } } }
+    }
+
+    function assemble_request ( ) {
+        v = this.getField('filename') ;
+        if (v) {
+            exa_filename = v.value ;
+        }
+        v = this.getField('filelist') ;
+        if (v) {
+            exa_filelist = v.value ;
+        }
+%       exa_filename = exa_filename.replace(/\\\\/g,'/') ;
+%       exa_filelist = exa_filelist.replace(/\\\\/g,'/') ;
+        str = "<?xml version='1.0' ?>\\n" ;
+        str = str+"<exa:request xmlns:exa='http://www.pragma-ade.com/schemas/example.rng'><exa:application>" ;
+        if (exa_filelist == "") {
+            exa_filelist = exa_registered ;
+        } else { if (exa_registered != "") {
+            exa_filelist = exa_filelist + "\\n" + exa_registered ;
+        } }
+        if (exa_command != "") {
+            str = str+"<exa:command>"+exa_command+"</exa:command>" ;
+        }
+        if (exa_option != "") {
+            str = str+"<exa:option>"+exa_option+"</exa:option>" ;
+        }
+        if (exa_filename != "") {
+            str = str+"<exa:filename>"+exa_filename+"</exa:filename>" ;
+        }
+        var fls = "" ;
+        if (exa_filelist != "") {
+            % old method, soon obsolete
+            lst = exa_filelist.split(/\\s/) ;
+            for (i=0;i<lst.length;i++) {
+                fls = fls+"<exa:entry>"+lst[i]+"</exa:entry>" ;
+            }
+        } else { if (exa_multiple) {
+            for (i=1;i<=100;i++) {
+                % console.println("file field "+i) ;
+                f = this.getField("filename-"+ i) ;
+%                 if (f) { if (f.value != "") {
+%                     if (g) { if (g.value == "") {
+%                         fls = fls+"<exa:entry>"+f.value+"</exa:entry>" ;
+%                     } else {
+%                         fls = fls+"<exa:entry label='" + g.value + "'>"+f.value+"</exa:entry>" ;
+%                     } } else {
+%                         fls = fls+"<exa:entry>"+f.value+"</exa:entry>" ;
+%                     }
+%                 } }
+                if (f) { if (f.value != "") {
+                    fls = fls + "<exa:entry" ;
+                    g = this.getField("dataname-"+ i) ;
+                    if (g) { if (g.value == "") {
+                        % console.println("a") ;
+                        fls = fls + ">" ;
+                    } else {
+                        % console.println("b") ;
+                        fls = fls + " label='" + g.value + "'>" ;
+                    } } else {
+                        % console.println("c") ;
+                        fls = fls + ">" ;
+                    }
+                    fls = fls + f.value + "</exa:entry>" ;
+                } }
+            }
+        } }
+        if (fls != "") {
+            str = str + "<exa:filelist>" + fls + "</exa:filelist>" ;
+        }
+        str = str + "</exa:application></exa:request>" ;
+        v = this.getField('exa:request') ;
+        if (v) {
+            v.value = str ;
+        }
+    }
+
+\stopJSpreamble
+
+\startJSpreamble request_3 used now
+
+    var exa_multiple = false ;
+
+    function setfilename ( suffixes ) {
+        if (event.targetName) {
+            var name = event.targetName ;
+            var fake = name.replace(/filename/,"fakename") ;
+        } else {
+            var name = 'filename' ;
+            var fake = 'fakename' ;
+        }
+        f = this.getField(fake) ;
+        if (f) {
+            f.browseForFileToSubmit() ;
+            if ((suffixes != "") && (f.value != "")) {
+                %
+                s = suffixes.replace(/,/g,"|") ;
+                r = new RegExp() ;
+                s = "\\\\.(" + s + ")$" ;
+                r.compile(s, "i") ;
+                if (f.value.search(r)<=0) {
+                    f.value = "" ;
+                    app.alert('This filetype is not permitted.') ;
+                %
+                % lst = suffixes.split(/,/) ;
+                % ok = false ;
+                % for (i=0;i<lst.length;i++) {
+                %     if (f.value == lst[i]) {
+                %         ok = true ;
+                %     }
+                % }
+                % if (! ok) {
+                %     f.value = "" ;
+                %     app.alert('This filetype is not permitted.') ;
+                %
+                }
+            }
+            g = this.getField(name) ;
+            if (g) {
+                g.value = f.value ;
+            }
+% we need to set the value of the selector to empty else
+% we get some funny preloading of multimeg files in spite
+% of the specs that say that xml fields will not get sent
+%             if (example_method == "XFDF" ) {
+%                 f.value = "" ;
+%             } else {
+%                 identify_example_url ;
+%                 if (example_url.indexOf("localhost")>=0) {
+%                     f.value = "" ;
+%                 }
+%             }
+        }
+        this.dirty = false ;
+    }
+
+    function addfilename () {
+        if (exa_multiple) {
+            h = this.getField("filelist") ;
+            g = this.getField("filename") ;
+            if ((g) && (h)) {
+                str = g.value ;
+                if (h.value == "") {
+                    h.value = str ;
+                } else {
+                    h.value = h.value + "\\n" + str ;
+                }
+                g.value = "" ;
+                this.value = "" ;
+            }
+        }
+        this.dirty = false ;
+    }
+
+    % this only works with client that assembles request
+
+    function registerfilename (str) {
+        if (str!="") {
+            h = this.getField("filelist") ;
+            if (h) {
+                if (h.value != "") {
+                    h.value = h.value + "\\n" ;
+                }
+                h.value = h.value + str ;
+            } else {
+                if (exa_registered != "") {
+                    exa_registered = exa_registered + "\\n" ;
+                }
+                exa_registered = exa_registered + str ;
+            }
+        }
+        console.show ;
+        console.println('registered files') ;
+        console.println("file: "+str) ;
+        console.println("list: "+exa_registered) ;
+        this.dirty = false ;
+    }
+
+    function checkfilename () {
+    }
+
+    function getfilename ( suffixes ) {
+        setfilename(suffixes) ;
+        checkfilename() ;
+        addfilename() ;
+    }
+
+    function resetfilename () {
+        do_erase_example_file("fakename") ;
+        do_erase_example_file("filename") ;
+        do_erase_example_file("filelist") ;
+        do_erase_example_list("filename") ;
+        do_erase_example_list("fakename") ;
+    }
+
+\stopJSpreamble
+
+\endinput
diff --git a/tex/context/base/mkiv/java-imp-fields.mkiv b/tex/context/base/mkiv/java-imp-fields.mkiv
new file mode 100644
index 000000000..5801c3216
--- /dev/null
+++ b/tex/context/base/mkiv/java-imp-fields.mkiv
@@ -0,0 +1,648 @@
+%D \module
+%D   [       file=java-imp-fields, % was java-fld
+%D        version=1998.05.20,
+%D          title=\CONTEXT\ JavaScript Macros,
+%D       subtitle=Field Support,
+%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 In \LUATEX\ the following does not work out well:
+%D
+%D \starttyping
+%D v = v.replace(/\\\\"e/g,"\\353") ;
+%D \stoptyping
+%D
+%D But this does:
+%D
+%D \starttyping
+%D v = String(v).replace(/\\\\"e/g,"\\353") ;
+%D \stoptyping
+%D
+%D Probably a \UNICODE\ issue. Beware, in \MKIV\ we have a
+%D different escaping of \type {\\}.
+%D
+%D Watch out: cf. the latest pdf specification we've changed On into Yes. Also,
+%D we've changed the test for the on value into !Off as we dón't know what value it
+%D gets in the reader.
+
+% Is this still okay? We can have unicode now, can't we? Anyway it's kind of
+% messy and unneeded in these unicode times.
+
+\startluasetups javascript:pdfencoding
+    local ctx_verbatim = context.verbatim
+    local utfbyte      = utf.byte
+    local sortedhash   = table.sortedhash
+
+    ctx_verbatim("{\n")
+    for accent, group in sortedhash(characters.tex.accentmapping) do
+        for character, mapping in sortedhash(group) do
+            if character == "" then
+                character = " "
+            end
+            if accent == '"' then
+                ctx_verbatim("    '\\\\%s%s' : '\\u%04X',\n",accent,character,utfbyte(mapping))
+            else
+                ctx_verbatim('    "\\\\%s%s" : "\\u%04X",\n',accent,character,utfbyte(mapping))
+            end
+        end
+    end
+    for command, mapping in sortedhash(characters.tex.commandmapping) do
+        ctx_verbatim('    "\\\\%s" : "\\u%04X",\n',command,utfbyte(mapping))
+    end
+ -- ctx_verbatim("    '\\\\<<' : '\\u00AB',\n")
+ -- ctx_verbatim("    '\\\\>>' : '\\u00BB',\n")
+    ctx_verbatim("}\n")
+
+\stopluasetups
+
+% maybe make { } tex braces in javascript code so that we can call lua
+
+\def\JavaScriptTeXAccentMapping{\luasetup{javascript:pdfencoding}}
+
+\startJSpreamble SanitizeTeXInput used later
+
+var TeXAccentMapping = \JavaScriptTeXAccentMapping
+
+function TeX_Replacer(original,str) {
+    return (TeXAccentMapping[str] || str) ;
+}
+
+function Sanitized_TeX_String(value) {
+    return (value.replace(/(\\..)/g, TeX_Replacer)) ;
+}
+
+var TeX_Key_Mode = 0 ;
+var TeX_Key_Char = "" ;
+
+function Initialize_TeX_Keystroke() {
+    TeX_Key_Char = "" ;
+    TeX_Key_Mode = 0 ;
+}
+
+function Sanitized_TeX_Keystroke(change) {
+    if (!event.willCommit) {
+    if (change=="\\") {
+        TeX_Key_Mode = 1 ;
+        return ("")
+    } else if (TeX_Key_Mode == 1) {
+        TeX_Key_Mode = 2 ;
+        TeX_Key_Char = change ;
+        return ("")
+    } else if (TeX_Key_Mode == 2) {
+        TeX_Key_Mode = 0 ;
+        TeX_Key_Char = "\\"+TeX_Key_Char+change ;
+        return (Sanitized_TeX_String(TeX_Key_Char))
+    } else {
+        TeX_Key_Mode = 0 ;
+        return (change)
+    }
+    }
+}
+
+function Initialize_TeX_Key() {
+    Initialize_TeX_Keystroke() ;
+}
+
+function Convert_TeX_Key() {
+    if (!event.willCommit) {
+        event.change = Sanitized_TeX_Keystroke(event.change) ;
+    }
+}
+
+function Convert_TeX_String() {
+    event.value = Sanitized_TeX_String(event.value) ;
+}
+
+\stopJSpreamble
+
+% \startJScode {Initialize_TeX_Key} uses {SanitizeTeXInput}
+%     Initialize_TeX_Keystroke() ;
+% \stopJScode
+%
+% \startJScode {Convert_TeX_Key} uses {SanitizeTeXInput}
+%     if (!event.willCommit) {
+%         event.change = Sanitized_TeX_Keystroke(event.change) ;
+%     }
+% \stopJScode
+%
+% \startJScode{Convert_TeX_String} uses {SanitizeTeXInput}
+%     event.value = Sanitized_TeX_String(event.value) ;
+% \stopJScode
+
+% was used now but we autocheck anyway so lets test this for a while
+
+\startJSpreamble FieldsStates used later
+
+var visible_field  = new Array() ;
+var visible_fields = 0 ;
+
+function PresetFields() {
+    this.syncAnnotScan() ;
+}
+
+function Preset_Fields() {
+    this.syncAnnotScan() ;
+}
+
+function Hide_When_Down() {
+    event.target.hidden = true ;
+}
+
+function Hide_Field(Name) {
+    var v = this.getField(Name) ;
+    if (v) {
+        v.hidden = true ;
+        v.readonly = true ;
+        this.dirty = false ;
+    }
+}
+
+function Do_Vide_Field(Name, Closable) {
+    var v = this.getField(Name) ;
+    if (v) {
+        ++visible_fields ;
+        visible_field[visible_fields] = Name ;
+        v.hidden = false ;
+        if (Closable) {
+            v.readonly = false ;
+            v.value = "Yes" ;
+        }
+        this.dirty = false ;
+    }
+}
+
+function Vide_Field(Name) {
+    Do_Vide_Field(Name,false) ;
+}
+
+function Vide_Hide_Field(Name) {
+    Do_Vide_Field(Name,true) ;
+}
+
+function Hide_Fields() {
+    while (visible_fields>0) {
+        Hide_Field(visible_field[visible_fields]) ;
+        --visible_fields ;
+    }
+}
+
+function Vide_Fields(Name) {
+    Hide_Fields() ;
+    Vide_Field(Name) ;
+}
+
+function Vide_Hide_Fields(Name) {
+    Hide_Fields() ;
+    Vide_Hide_Field(Name) ;
+}
+
+function Toggle_Hide(Name) {
+    var v = this.getField(Name) ;
+    if (v) {
+        v.hidden = !v.hidden ;
+        this.dirty = false ;
+    }
+}
+
+function Field_On(Name) {
+    v = this.getField(Name) ;
+    if (v) {
+        v.value = "Yes" ;
+        this.dirty = false ;
+    }
+}
+
+function Field_Off(Name) {
+    var v = this.getField(Name) ;
+    if (v) {
+        v.value = "Off" ;
+        this.dirty = false ;
+    }
+}
+
+function Toggle_Value(Name) {
+    var v = this.getField(Name) ;
+    if (v) {
+        if (v.value != "Off") {
+            v.value = "Off" ;
+        } else {
+            v.value = "Yes" ;
+        }
+    }
+    this.dirty = false ;
+}
+
+function Toggle_Read(Name) {
+    var v = this.getField(Name);
+    if (v) {
+        v.readonly = !v.readonly ;
+    }
+}
+
+function Flip_Fields(Name) {
+    var Names = Name.split(",") ;
+    for (var i=0; i < Names.length; i++) {
+        v = this.getField(Names[i]) ;
+        if (v) {
+            v.hidden = !v.hidden ;
+            v.value = "Yes" ;
+        }
+    }
+}
+
+function Forget_Changes() {
+    this.dirty = false ;
+}
+
+function ForgetChanges() {
+    this.dirty = false ;
+}
+
+function Step_Fields (Name, First, Last) {
+    for (var i = Number(First) ; i <= Number(Last) ; i++) {
+        var s = Name + ":" + i ;
+        var v = this.getField(s) ;
+        if (v) {
+            ++visible_fields ;
+            visible_field[visible_fields] = s ;
+            if (v.hidden) {
+                v.hidden   = false ;
+                this.dirty = false ;
+                return ;
+            }
+        }
+    }
+}
+\stopJSpreamble
+
+\definereference[VideFields]   [JS(Vide_Fields)]
+\definereference[HideFields]   [JS(Hide_Fields)]
+\definereference[ForgetChanges][JS(Forget_Changes)]
+\definereference[StepFields]   [JS(Step_Fields)]
+
+% This can be done more efficient, by keeping track of the
+% current top of the stack.
+
+\startJSpreamble FieldStack used later
+
+function Field_Name(FieldSet,i) {
+    return this.getField(FieldSet + ":" + i)
+}
+
+function Reset_Fields(FieldSet) {
+    var i = 1 ;
+    while (true) {
+        var v = Field_Name(FieldSet,i) ;
+        if (!v) {
+            break ;
+        } else {
+            v.value = "Off" ;
+        }
+        i++ ;
+    }
+    this.dirty = false ;
+}
+
+function Set_Fields(FieldSet) {
+    var i = 1 ;
+    while (true) {
+        var v = Field_Name(FieldSet,i) ;
+        if (!v) {
+            break ;
+        } else {
+            v.value = "Yes" ;
+        }
+        i++ ;
+    }
+    this.dirty = false ;
+}
+
+function Set_Field(FieldSet, FieldName) {
+    Reset_Fields(FieldSet) ;
+    var v = Field_Name(FieldSet,FieldName) ;
+    if (v) {
+        v.value = "Yes" ;
+        this.dirty = false ;
+    }
+}
+
+function Reset_Field(FieldSet, FieldName) {
+    Set_Fields(FieldSet) ;
+    var v = Field_Name(FieldSet,FieldName) ;
+    if (v) {
+        v.value = "Off" ;
+        this.dirty = false ;
+    }
+}
+
+function Walk_Field(FieldSet) {
+    var i = 1 ;
+    this.syncAnnotScan();
+    while (true) {
+        var v = Field_Name(FieldSet,i) ;
+        if (v) {
+            if (v.value != "Off") {
+                v.value = "Off" ;
+                v = Field_Name(FieldSet,i + 1) ;
+                if (! v) {
+                    v = Field_Name(FieldSet,1) ;
+                } else {
+                }
+                if (v) {
+                    v.value = "Yes" ;
+                }
+                break ;
+            }
+            i++ ;
+        } else {
+            v = Field_Name(FieldSet,1) ;
+            if (v) {
+                v.value = "Yes" ;
+            }
+            break ;
+        }
+    }
+    this.dirty = false ;
+}
+
+var FieldSets = new Array() ;
+
+function Do_Get_Check_Walk_Field(FieldSet) {
+    var f = FieldSets[FieldSet]
+    if (! f) {
+        f = new Array() ;
+        f.number = 0 ;
+        f.delay = 500 ;
+        f.paused = false ;
+        f.running = false ;
+        f.name = FieldSet ;
+        f.timeout = null ;
+        f.repeat = true ;
+        f.total = 0 ;
+        f.pauseset = new Array() ;
+        FieldSets[FieldSet] = f ;
+        for (var i=1; i>0; i++) {
+            var v = Field_Name(FieldSet,i) ;
+            if (! v) {
+                f.total = i - 1 ;
+                break ;
+            }
+        }
+        f.start = 0 ;
+        f.stop = f.total ;
+        f.pause = 0 ;
+    }
+    this.dirty = false ;
+    return f
+}
+
+function Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,n) {
+    var v = Field_Name(FieldSet,fieldset.number) ;
+    if (v) {
+        if (v.value != "Off") {
+            v.value = "Off" ;
+        }
+    }
+    v = Field_Name(FieldSet,n) ;
+    if (v) {
+        fieldset.number = n ;
+        v.value = "Yes" ;
+        if (fieldset.pauseset[n]) {
+       //     fieldset.pause = n ;
+       //     Do_Stop_Auto_Walk_Field(Fieldset) ;
+                Do_Stop_Auto_Walk_Field(FieldSet) ;
+                fieldset.paused = true ;
+        }
+    }
+    this.dirty = false ;
+}
+
+function Do_Next_Auto_Walk_Field(FieldSet) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        if (fieldset.number >= fieldset.stop) {
+            if (fieldset.repeat == false) {
+                fieldset.running = false ;
+                Do_Stop_Auto_Walk_Field(fieldset) ;
+            } else {
+                Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,fieldset.start) ;
+            }
+        } else {
+            Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,fieldset.number+1) ;
+        }
+        this.dirty = false ;
+    }
+}
+
+function Do_Stop_Auto_Walk_Field(FieldSet) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        try {
+            app.clearInterval(fieldset.timeout) ;
+            app.clearTimeOut(fieldset.timeout) ;
+        } catch (e) {
+        }
+        this.dirty = false ;
+    }
+}
+
+function Do_Start_Auto_Walk_Field(FieldSet) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        Do_Stop_Auto_Walk_Field(FieldSet) ;
+        Do_Next_Auto_Walk_Field(FieldSet) ;
+        fieldset.timeout = app.setInterval("Do_Next_Auto_Walk_Field('"+FieldSet+"')", fieldset.delay) ;
+        this.dirty = false ;
+    }
+}
+
+function Start_Walk_Field(FieldSet, Delay) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        fieldset.number = 0 ;
+        if (Delay) {
+            fieldset.delay = Delay ;
+        }
+        Reset_Fields(FieldSet) ;
+        Do_Start_Auto_Walk_Field(FieldSet) ;
+        fieldset.running = true ;
+        fieldset.paused = false ;
+    }
+}
+
+function Pause_Walk_Field(FieldSet) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        if (fieldset.running) {
+            if (fieldset.paused) {
+                Do_Start_Auto_Walk_Field(FieldSet) ;
+                fieldset.paused = false ;
+            } else {
+                Do_Stop_Auto_Walk_Field(FieldSet) ;
+                fieldset.paused = true ;
+            }
+        }
+    }
+}
+
+function Start_Pause_Walk_Field(FieldSet, Delay, Option) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        if (Option == "once") {
+            fieldset.repeat = false ;
+        } else if (Option == "pause") {
+            fieldset.repeat = false ;
+        } else {
+            fieldset.repeat = true ;
+        }
+        if (Option == "pause") {
+            for (i=3; i<arguments.length; i++) {
+                fieldset.pauseset[parseInt(arguments[i])] = true ;
+            }
+            if (fieldset.pause == fieldset.stop) {
+                fieldset.start = 1 ;
+                fieldset.pause = 0 ;
+            } else if (fieldset.pause > 1) {
+                fieldset.start = fieldset.pause - 1 ;
+            } else {
+                fieldset.start = 1 ;
+            }
+            fieldset.stop = fieldset.total ;
+        } else {
+            var Start = arguments[3] ;
+            var Stop = arguments[4] ;
+            if (typeof Start == "string") {
+                fieldset.start = parseInt(Start) ;
+            } else if (typeof Start == "number") {
+                fieldset.start = Start ;
+            } else {
+                fieldset.start = 1 ;
+            }
+            if (typeof Stop == "string") {
+                fieldset.stop = parseInt(Stop) ;
+            } else if (typeof Stop == "number") {
+                fieldset.stop = Stop ;
+            } else {
+                fieldset.stop = fieldset.total ;
+            }
+            fieldset.pause = 0 ;
+        }
+        if (fieldset.running) {
+            if (fieldset.paused) {
+                Do_Start_Auto_Walk_Field(FieldSet) ;
+                fieldset.paused = false ;
+            } else {
+                Do_Stop_Auto_Walk_Field(FieldSet) ;
+                fieldset.paused = true ;
+            }
+        } else {
+            fieldset.number = fieldset.start - 1  ;
+            if (Delay) {
+                fieldset.delay = Delay ;
+            }
+            Reset_Fields(FieldSet) ;
+            Do_Start_Auto_Walk_Field(FieldSet) ;
+            fieldset.running = true ;
+            fieldset.paused = false ;
+        }
+    }
+}
+
+function Stop_Walk_Field(FieldSet) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        Do_Stop_Auto_Walk_Field(FieldSet) ;
+        fieldset.running = false ;
+        fieldset.paused = false ;
+    }
+}
+
+function Reset_Walk_Field(FieldSet) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        Do_Stop_Auto_Walk_Field(FieldSet) ;
+        fieldset.number = 0 ;
+        fieldset.running = false ;
+        fieldset.paused = false ;
+        Reset_Fields(FieldSet) ;
+    }
+}
+
+function Previous_Walk_Field(FieldSet) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        Do_Stop_Auto_Walk_Field(FieldSet) ;
+        fieldset.running = false ;
+        fieldset.paused = false ;
+        if (fieldset.number>0) {
+            var v = Field_Name(FieldSet,fieldset.number) ;
+            if (v) {
+                if (v.value != "Off") {
+                    v.value = "Off" ;
+                }
+            }
+            fieldset.number-- ;
+            v = Field_Name(FieldSet,fieldset.number) ;
+            if (v) {
+                v.value = "Yes" ;
+            }
+            this.dirty = false ;
+        }
+    }
+}
+
+function Next_Walk_Field(FieldSet) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        Do_Stop_Auto_Walk_Field(FieldSet) ;
+        fieldset.running = false ;
+        fieldset.paused = false ;
+        var f = fieldset.number + 1 ;
+        var v = Field_Name(FieldSet,f) ;
+        if (v) {
+            var v = Field_Name(FieldSet,fieldset.number) ;
+            if (v) {
+                if (v.value != "Off") {
+                    v.value = "Off" ;
+                }
+            }
+            fieldset.number++ ;
+            v = Field_Name(FieldSet,fieldset.number) ;
+            if (v) {
+                v.value = "Yes" ;
+            }
+            this.dirty = false ;
+        }
+    }
+}
+
+function Set_Walk_Field_Delay(FieldSet, Delay) {
+    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
+    if (fieldset) {
+        if (Delay) {
+            fieldset.delay = Delay ;
+            if (fieldset.running) {
+                Do_Stop_Auto_Walk_Field(FieldSet) ;
+                Do_Start_Auto_Walk_Field(FieldSet) ;
+            }
+        }
+    }
+}
+
+\stopJSpreamble
+
+\definereference[Walk]        [JS(Walk_Field)]
+\definereference[StartWalk]   [JS(Start_Walk_Field)]
+\definereference[StopWalk]    [JS(Stop_Walk_Field)]
+\definereference[PauseWalk]   [JS(Pause_Walk_Field)]
+\definereference[ResetWalk]   [JS(Reset_Walk_Field)]
+\definereference[PreviousWalk][JS(Previous_Walk_Field)]
+\definereference[NextWalk]    [JS(Next_Walk_Field)]
+\definereference[SetWalkDelay][JS(Set_Walk_Field_Delay)]
+
+\endinput
diff --git a/tex/context/base/mkiv/java-imp-fil.mkiv b/tex/context/base/mkiv/java-imp-fil.mkiv
deleted file mode 100644
index 808950f28..000000000
--- a/tex/context/base/mkiv/java-imp-fil.mkiv
+++ /dev/null
@@ -1,52 +0,0 @@
-%D \module
-%D   [       file=java-fil,
-%D        version=1998.06.01,
-%D          title=\CONTEXT\ JavaScript Macros,
-%D       subtitle=Filing and Printing,
-%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.
-
-\startJSpreamble Auxiliary used now
-
-    function DocumentFileName() {
-        var Paths = this.path.split("/") ;
-        Paths = Paths[Paths.length-1].split(".") ;
-        return(Paths[0])
-    }
-
-    function Print_Page_Range(From,To) {
-        if ((Number(From)>0) && (Number(To) >= Number(From))) {
-            var myFrom = Number(From)-1 ;
-            var myTo = Number(To)-1 ;
-            this.print(false,myFrom,myTo,true) ;
-        }
-    }
-
-    function Print_This_Page() {
-        this.print(false,this.pageNum,this.pageNum,true) ;
-    }
-
-\stopJSpreamble
-
-\definereference
-  [PrintSubPaginas]
-  [JS(Print_Page_Range{\firstsubpage,\lastsubpage})]
-
-\definereference
-  [PrintSubPages]
-  [JS(Print_Page_Range{\firstsubpage,\lastsubpage})]
-
-\definereference
-  [PrintDezePagina]
-  [JS(Print_This_Page)]
-
-\definereference
-  [PrintThisPage]
-  [JS(Print_This_Page)]
-
-\endinput
diff --git a/tex/context/base/mkiv/java-imp-fld.mkiv b/tex/context/base/mkiv/java-imp-fld.mkiv
deleted file mode 100644
index 559ab01b3..000000000
--- a/tex/context/base/mkiv/java-imp-fld.mkiv
+++ /dev/null
@@ -1,648 +0,0 @@
-%D \module
-%D   [       file=java-fld,
-%D        version=1998.05.20,
-%D          title=\CONTEXT\ JavaScript Macros,
-%D       subtitle=Field Support,
-%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 In \LUATEX\ the following does not work out well:
-%D
-%D \starttyping
-%D v = v.replace(/\\\\"e/g,"\\353") ;
-%D \stoptyping
-%D
-%D But this does:
-%D
-%D \starttyping
-%D v = String(v).replace(/\\\\"e/g,"\\353") ;
-%D \stoptyping
-%D
-%D Probably a \UNICODE\ issue. Beware, in \MKIV\ we have a
-%D different escaping of \type {\\}.
-%D
-%D Watch out: cf. the latest pdf specification we've changed
-%D On into Yes. Also, we've changed the test for the on value
-%D into !Off as we dón't know what value it gets in the reader.
-
-% Is this still okay? We can have unicode now, can't we? Anyway it's kind of
-% messy and unneeded in these unicode times.
-
-\startluasetups javascript:pdfencoding
-    local ctx_verbatim = context.verbatim
-    local utfbyte      = utf.byte
-    local sortedhash   = table.sortedhash
-
-    ctx_verbatim("{\n")
-    for accent, group in sortedhash(characters.tex.accentmapping) do
-        for character, mapping in sortedhash(group) do
-            if character == "" then
-                character = " "
-            end
-            if accent == '"' then
-                ctx_verbatim("    '\\\\%s%s' : '\\u%04X',\n",accent,character,utfbyte(mapping))
-            else
-                ctx_verbatim('    "\\\\%s%s" : "\\u%04X",\n',accent,character,utfbyte(mapping))
-            end
-        end
-    end
-    for command, mapping in sortedhash(characters.tex.commandmapping) do
-        ctx_verbatim('    "\\\\%s" : "\\u%04X",\n',command,utfbyte(mapping))
-    end
- -- ctx_verbatim("    '\\\\<<' : '\\u00AB',\n")
- -- ctx_verbatim("    '\\\\>>' : '\\u00BB',\n")
-    ctx_verbatim("}\n")
-
-\stopluasetups
-
-% maybe make { } tex braces in javascript code so that we can call lua
-
-\def\JavaScriptTeXAccentMapping{\luasetup{javascript:pdfencoding}}
-
-\startJSpreamble SanitizeTeXInput used later
-
-var TeXAccentMapping = \JavaScriptTeXAccentMapping
-
-function TeX_Replacer(original,str) {
-    return (TeXAccentMapping[str] || str) ;
-}
-
-function Sanitized_TeX_String(value) {
-    return (value.replace(/(\\..)/g, TeX_Replacer)) ;
-}
-
-var TeX_Key_Mode = 0 ;
-var TeX_Key_Char = "" ;
-
-function Initialize_TeX_Keystroke() {
-    TeX_Key_Char = "" ;
-    TeX_Key_Mode = 0 ;
-}
-
-function Sanitized_TeX_Keystroke(change) {
-    if (!event.willCommit) {
-    if (change=="\\") {
-        TeX_Key_Mode = 1 ;
-        return ("")
-    } else if (TeX_Key_Mode == 1) {
-        TeX_Key_Mode = 2 ;
-        TeX_Key_Char = change ;
-        return ("")
-    } else if (TeX_Key_Mode == 2) {
-        TeX_Key_Mode = 0 ;
-        TeX_Key_Char = "\\"+TeX_Key_Char+change ;
-        return (Sanitized_TeX_String(TeX_Key_Char))
-    } else {
-        TeX_Key_Mode = 0 ;
-        return (change)
-    }
-    }
-}
-
-function Initialize_TeX_Key() {
-    Initialize_TeX_Keystroke() ;
-}
-
-function Convert_TeX_Key() {
-    if (!event.willCommit) {
-        event.change = Sanitized_TeX_Keystroke(event.change) ;
-    }
-}
-
-function Convert_TeX_String() {
-    event.value = Sanitized_TeX_String(event.value) ;
-}
-
-\stopJSpreamble
-
-% \startJScode {Initialize_TeX_Key} uses {SanitizeTeXInput}
-%     Initialize_TeX_Keystroke() ;
-% \stopJScode
-%
-% \startJScode {Convert_TeX_Key} uses {SanitizeTeXInput}
-%     if (!event.willCommit) {
-%         event.change = Sanitized_TeX_Keystroke(event.change) ;
-%     }
-% \stopJScode
-%
-% \startJScode{Convert_TeX_String} uses {SanitizeTeXInput}
-%     event.value = Sanitized_TeX_String(event.value) ;
-% \stopJScode
-
-% was used now but we autocheck anyway so lets test this for a while
-
-\startJSpreamble FieldsStates used later
-
-var visible_field  = new Array() ;
-var visible_fields = 0 ;
-
-function PresetFields() {
-    this.syncAnnotScan() ;
-}
-
-function Preset_Fields() {
-    this.syncAnnotScan() ;
-}
-
-function Hide_When_Down() {
-    event.target.hidden = true ;
-}
-
-function Hide_Field(Name) {
-    var v = this.getField(Name) ;
-    if (v) {
-        v.hidden = true ;
-        v.readonly = true ;
-        this.dirty = false ;
-    }
-}
-
-function Do_Vide_Field(Name, Closable) {
-    var v = this.getField(Name) ;
-    if (v) {
-        ++visible_fields ;
-        visible_field[visible_fields] = Name ;
-        v.hidden = false ;
-        if (Closable) {
-            v.readonly = false ;
-            v.value = "Yes" ;
-        }
-        this.dirty = false ;
-    }
-}
-
-function Vide_Field(Name) {
-    Do_Vide_Field(Name,false) ;
-}
-
-function Vide_Hide_Field(Name) {
-    Do_Vide_Field(Name,true) ;
-}
-
-function Hide_Fields() {
-    while (visible_fields>0) {
-        Hide_Field(visible_field[visible_fields]) ;
-        --visible_fields ;
-    }
-}
-
-function Vide_Fields(Name) {
-    Hide_Fields() ;
-    Vide_Field(Name) ;
-}
-
-function Vide_Hide_Fields(Name) {
-    Hide_Fields() ;
-    Vide_Hide_Field(Name) ;
-}
-
-function Toggle_Hide(Name) {
-    var v = this.getField(Name) ;
-    if (v) {
-        v.hidden = !v.hidden ;
-        this.dirty = false ;
-    }
-}
-
-function Field_On(Name) {
-    v = this.getField(Name) ;
-    if (v) {
-        v.value = "Yes" ;
-        this.dirty = false ;
-    }
-}
-
-function Field_Off(Name) {
-    var v = this.getField(Name) ;
-    if (v) {
-        v.value = "Off" ;
-        this.dirty = false ;
-    }
-}
-
-function Toggle_Value(Name) {
-    var v = this.getField(Name) ;
-    if (v) {
-        if (v.value != "Off") {
-            v.value = "Off" ;
-        } else {
-            v.value = "Yes" ;
-        }
-    }
-    this.dirty = false ;
-}
-
-function Toggle_Read(Name) {
-    var v = this.getField(Name);
-    if (v) {
-        v.readonly = !v.readonly ;
-    }
-}
-
-function Flip_Fields(Name) {
-    var Names = Name.split(",") ;
-    for (var i=0; i < Names.length; i++) {
-        v = this.getField(Names[i]) ;
-        if (v) {
-            v.hidden = !v.hidden ;
-            v.value = "Yes" ;
-        }
-    }
-}
-
-function Forget_Changes() {
-    this.dirty = false ;
-}
-
-function ForgetChanges() {
-    this.dirty = false ;
-}
-
-function Step_Fields (Name, First, Last) {
-    for (var i = Number(First) ; i <= Number(Last) ; i++) {
-        var s = Name + ":" + i ;
-        var v = this.getField(s) ;
-        if (v) {
-            ++visible_fields ;
-            visible_field[visible_fields] = s ;
-            if (v.hidden) {
-                v.hidden   = false ;
-                this.dirty = false ;
-                return ;
-            }
-        }
-    }
-}
-\stopJSpreamble
-
-\definereference[VideFields]   [JS(Vide_Fields)]
-\definereference[HideFields]   [JS(Hide_Fields)]
-\definereference[ForgetChanges][JS(Forget_Changes)]
-\definereference[StepFields]   [JS(Step_Fields)]
-
-% This can be done more efficient, by keeping track of the
-% current top of the stack.
-
-\startJSpreamble FieldStack used later
-
-function Field_Name(FieldSet,i) {
-    return this.getField(FieldSet + ":" + i)
-}
-
-function Reset_Fields(FieldSet) {
-    var i = 1 ;
-    while (true) {
-        var v = Field_Name(FieldSet,i) ;
-        if (!v) {
-            break ;
-        } else {
-            v.value = "Off" ;
-        }
-        i++ ;
-    }
-    this.dirty = false ;
-}
-
-function Set_Fields(FieldSet) {
-    var i = 1 ;
-    while (true) {
-        var v = Field_Name(FieldSet,i) ;
-        if (!v) {
-            break ;
-        } else {
-            v.value = "Yes" ;
-        }
-        i++ ;
-    }
-    this.dirty = false ;
-}
-
-function Set_Field(FieldSet, FieldName) {
-    Reset_Fields(FieldSet) ;
-    var v = Field_Name(FieldSet,FieldName) ;
-    if (v) {
-        v.value = "Yes" ;
-        this.dirty = false ;
-    }
-}
-
-function Reset_Field(FieldSet, FieldName) {
-    Set_Fields(FieldSet) ;
-    var v = Field_Name(FieldSet,FieldName) ;
-    if (v) {
-        v.value = "Off" ;
-        this.dirty = false ;
-    }
-}
-
-function Walk_Field(FieldSet) {
-    var i = 1 ;
-    this.syncAnnotScan();
-    while (true) {
-        var v = Field_Name(FieldSet,i) ;
-        if (v) {
-            if (v.value != "Off") {
-                v.value = "Off" ;
-                v = Field_Name(FieldSet,i + 1) ;
-                if (! v) {
-                    v = Field_Name(FieldSet,1) ;
-                } else {
-                }
-                if (v) {
-                    v.value = "Yes" ;
-                }
-                break ;
-            }
-            i++ ;
-        } else {
-            v = Field_Name(FieldSet,1) ;
-            if (v) {
-                v.value = "Yes" ;
-            }
-            break ;
-        }
-    }
-    this.dirty = false ;
-}
-
-var FieldSets = new Array() ;
-
-function Do_Get_Check_Walk_Field(FieldSet) {
-    var f = FieldSets[FieldSet]
-    if (! f) {
-        f = new Array() ;
-        f.number = 0 ;
-        f.delay = 500 ;
-        f.paused = false ;
-        f.running = false ;
-        f.name = FieldSet ;
-        f.timeout = null ;
-        f.repeat = true ;
-        f.total = 0 ;
-        f.pauseset = new Array() ;
-        FieldSets[FieldSet] = f ;
-        for (var i=1; i>0; i++) {
-            var v = Field_Name(FieldSet,i) ;
-            if (! v) {
-                f.total = i - 1 ;
-                break ;
-            }
-        }
-        f.start = 0 ;
-        f.stop = f.total ;
-        f.pause = 0 ;
-    }
-    this.dirty = false ;
-    return f
-}
-
-function Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,n) {
-    var v = Field_Name(FieldSet,fieldset.number) ;
-    if (v) {
-        if (v.value != "Off") {
-            v.value = "Off" ;
-        }
-    }
-    v = Field_Name(FieldSet,n) ;
-    if (v) {
-        fieldset.number = n ;
-        v.value = "Yes" ;
-        if (fieldset.pauseset[n]) {
-       //     fieldset.pause = n ;
-       //     Do_Stop_Auto_Walk_Field(Fieldset) ;
-                Do_Stop_Auto_Walk_Field(FieldSet) ;
-                fieldset.paused = true ;
-        }
-    }
-    this.dirty = false ;
-}
-
-function Do_Next_Auto_Walk_Field(FieldSet) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        if (fieldset.number >= fieldset.stop) {
-            if (fieldset.repeat == false) {
-                fieldset.running = false ;
-                Do_Stop_Auto_Walk_Field(fieldset) ;
-            } else {
-                Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,fieldset.start) ;
-            }
-        } else {
-            Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,fieldset.number+1) ;
-        }
-        this.dirty = false ;
-    }
-}
-
-function Do_Stop_Auto_Walk_Field(FieldSet) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        try {
-            app.clearInterval(fieldset.timeout) ;
-            app.clearTimeOut(fieldset.timeout) ;
-        } catch (e) {
-        }
-        this.dirty = false ;
-    }
-}
-
-function Do_Start_Auto_Walk_Field(FieldSet) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        Do_Stop_Auto_Walk_Field(FieldSet) ;
-        Do_Next_Auto_Walk_Field(FieldSet) ;
-        fieldset.timeout = app.setInterval("Do_Next_Auto_Walk_Field('"+FieldSet+"')", fieldset.delay) ;
-        this.dirty = false ;
-    }
-}
-
-function Start_Walk_Field(FieldSet, Delay) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        fieldset.number = 0 ;
-        if (Delay) {
-            fieldset.delay = Delay ;
-        }
-        Reset_Fields(FieldSet) ;
-        Do_Start_Auto_Walk_Field(FieldSet) ;
-        fieldset.running = true ;
-        fieldset.paused = false ;
-    }
-}
-
-function Pause_Walk_Field(FieldSet) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        if (fieldset.running) {
-            if (fieldset.paused) {
-                Do_Start_Auto_Walk_Field(FieldSet) ;
-                fieldset.paused = false ;
-            } else {
-                Do_Stop_Auto_Walk_Field(FieldSet) ;
-                fieldset.paused = true ;
-            }
-        }
-    }
-}
-
-function Start_Pause_Walk_Field(FieldSet, Delay, Option) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        if (Option == "once") {
-            fieldset.repeat = false ;
-        } else if (Option == "pause") {
-            fieldset.repeat = false ;
-        } else {
-            fieldset.repeat = true ;
-        }
-        if (Option == "pause") {
-            for (i=3; i<arguments.length; i++) {
-                fieldset.pauseset[parseInt(arguments[i])] = true ;
-            }
-            if (fieldset.pause == fieldset.stop) {
-                fieldset.start = 1 ;
-                fieldset.pause = 0 ;
-            } else if (fieldset.pause > 1) {
-                fieldset.start = fieldset.pause - 1 ;
-            } else {
-                fieldset.start = 1 ;
-            }
-            fieldset.stop = fieldset.total ;
-        } else {
-            var Start = arguments[3] ;
-            var Stop = arguments[4] ;
-            if (typeof Start == "string") {
-                fieldset.start = parseInt(Start) ;
-            } else if (typeof Start == "number") {
-                fieldset.start = Start ;
-            } else {
-                fieldset.start = 1 ;
-            }
-            if (typeof Stop == "string") {
-                fieldset.stop = parseInt(Stop) ;
-            } else if (typeof Stop == "number") {
-                fieldset.stop = Stop ;
-            } else {
-                fieldset.stop = fieldset.total ;
-            }
-            fieldset.pause = 0 ;
-        }
-        if (fieldset.running) {
-            if (fieldset.paused) {
-                Do_Start_Auto_Walk_Field(FieldSet) ;
-                fieldset.paused = false ;
-            } else {
-                Do_Stop_Auto_Walk_Field(FieldSet) ;
-                fieldset.paused = true ;
-            }
-        } else {
-            fieldset.number = fieldset.start - 1  ;
-            if (Delay) {
-                fieldset.delay = Delay ;
-            }
-            Reset_Fields(FieldSet) ;
-            Do_Start_Auto_Walk_Field(FieldSet) ;
-            fieldset.running = true ;
-            fieldset.paused = false ;
-        }
-    }
-}
-
-function Stop_Walk_Field(FieldSet) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        Do_Stop_Auto_Walk_Field(FieldSet) ;
-        fieldset.running = false ;
-        fieldset.paused = false ;
-    }
-}
-
-function Reset_Walk_Field(FieldSet) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        Do_Stop_Auto_Walk_Field(FieldSet) ;
-        fieldset.number = 0 ;
-        fieldset.running = false ;
-        fieldset.paused = false ;
-        Reset_Fields(FieldSet) ;
-    }
-}
-
-function Previous_Walk_Field(FieldSet) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        Do_Stop_Auto_Walk_Field(FieldSet) ;
-        fieldset.running = false ;
-        fieldset.paused = false ;
-        if (fieldset.number>0) {
-            var v = Field_Name(FieldSet,fieldset.number) ;
-            if (v) {
-                if (v.value != "Off") {
-                    v.value = "Off" ;
-                }
-            }
-            fieldset.number-- ;
-            v = Field_Name(FieldSet,fieldset.number) ;
-            if (v) {
-                v.value = "Yes" ;
-            }
-            this.dirty = false ;
-        }
-    }
-}
-
-function Next_Walk_Field(FieldSet) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        Do_Stop_Auto_Walk_Field(FieldSet) ;
-        fieldset.running = false ;
-        fieldset.paused = false ;
-        var f = fieldset.number + 1 ;
-        var v = Field_Name(FieldSet,f) ;
-        if (v) {
-            var v = Field_Name(FieldSet,fieldset.number) ;
-            if (v) {
-                if (v.value != "Off") {
-                    v.value = "Off" ;
-                }
-            }
-            fieldset.number++ ;
-            v = Field_Name(FieldSet,fieldset.number) ;
-            if (v) {
-                v.value = "Yes" ;
-            }
-            this.dirty = false ;
-        }
-    }
-}
-
-function Set_Walk_Field_Delay(FieldSet, Delay) {
-    var fieldset = Do_Get_Check_Walk_Field(FieldSet) ;
-    if (fieldset) {
-        if (Delay) {
-            fieldset.delay = Delay ;
-            if (fieldset.running) {
-                Do_Stop_Auto_Walk_Field(FieldSet) ;
-                Do_Start_Auto_Walk_Field(FieldSet) ;
-            }
-        }
-    }
-}
-
-\stopJSpreamble
-
-\definereference[Walk]        [JS(Walk_Field)]
-\definereference[StartWalk]   [JS(Start_Walk_Field)]
-\definereference[StopWalk]    [JS(Stop_Walk_Field)]
-\definereference[PauseWalk]   [JS(Pause_Walk_Field)]
-\definereference[ResetWalk]   [JS(Reset_Walk_Field)]
-\definereference[PreviousWalk][JS(Previous_Walk_Field)]
-\definereference[NextWalk]    [JS(Next_Walk_Field)]
-\definereference[SetWalkDelay][JS(Set_Walk_Field_Delay)]
-
-\endinput
diff --git a/tex/context/base/mkiv/java-imp-highlight.mkiv b/tex/context/base/mkiv/java-imp-highlight.mkiv
new file mode 100644
index 000000000..b55628f4b
--- /dev/null
+++ b/tex/context/base/mkiv/java-imp-highlight.mkiv
@@ -0,0 +1,34 @@
+%D \module
+%D   [       file=java-imp-highlightm, % was: java-rhh
+%D        version=2010.02.01,
+%D          title=\CONTEXT\ JavaScript Macros,
+%D       subtitle=Runtime Highlight Hack,
+%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 As hightlighting is rather intrusive it makes sense to turn it off when
+%D using nice appearances.
+
+% app.runtimeHighlightColor = [ "T" ] ;
+%
+% var SavedAlwaysShowFocus = app.alwaysShowFocus ;
+% app.alwaysShowFocus  = true ;
+% "app.alwaysShowFocus  = SavedAlwaysShowFocus ; "
+
+\startJSpreamble RuntimeHighlightHack used now
+    var SavedHighlightState = app.runtimeHighlight ;
+    var SavedFocusRectState = app.focusRect ;
+    app.runtimeHighlight = false ;
+    app.focusRect        = true ;
+    this.setAction("WillClose",
+        "app.runtimeHighlight = SavedHighlightState ; " +
+        "app.focusRect        = SavedFocusRectState ; "
+    ) ;
+\stopJSpreamble
+
+\endinput
diff --git a/tex/context/base/mkiv/java-imp-print.mkiv b/tex/context/base/mkiv/java-imp-print.mkiv
new file mode 100644
index 000000000..3d5325ff0
--- /dev/null
+++ b/tex/context/base/mkiv/java-imp-print.mkiv
@@ -0,0 +1,52 @@
+%D \module
+%D   [       file=java-imp-print, % was: java-fil
+%D        version=1998.06.01,
+%D          title=\CONTEXT\ JavaScript Macros,
+%D       subtitle=Filing and Printing,
+%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.
+
+\startJSpreamble auxiliary used now
+
+    function DocumentFileName() {
+        var Paths = this.path.split("/") ;
+        Paths = Paths[Paths.length-1].split(".") ;
+        return(Paths[0])
+    }
+
+    function Print_Page_Range(From,To) {
+        if ((Number(From)>0) && (Number(To) >= Number(From))) {
+            var myFrom = Number(From)-1 ;
+            var myTo = Number(To)-1 ;
+            this.print(false,myFrom,myTo,true) ;
+        }
+    }
+
+    function Print_This_Page() {
+        this.print(false,this.pageNum,this.pageNum,true) ;
+    }
+
+\stopJSpreamble
+
+\definereference
+  [PrintSubPaginas]
+  [JS(Print_Page_Range{\firstsubpage,\lastsubpage})]
+
+\definereference
+  [PrintSubPages]
+  [JS(Print_Page_Range{\firstsubpage,\lastsubpage})]
+
+\definereference
+  [PrintDezePagina]
+  [JS(Print_This_Page)]
+
+\definereference
+  [PrintThisPage]
+  [JS(Print_This_Page)]
+
+\endinput
diff --git a/tex/context/base/mkiv/java-imp-rhh.mkiv b/tex/context/base/mkiv/java-imp-rhh.mkiv
deleted file mode 100644
index 5f057f550..000000000
--- a/tex/context/base/mkiv/java-imp-rhh.mkiv
+++ /dev/null
@@ -1,34 +0,0 @@
-%D \module
-%D   [       file=java-rhh,
-%D        version=2010.02.01,
-%D          title=\CONTEXT\ JavaScript Macros,
-%D       subtitle=Runtime Highlight Hack,
-%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 As hightlighting is rather intrusive it makes sense to turn it off when
-%D using nice appearances.
-
-% app.runtimeHighlightColor = [ "T" ] ;
-%
-% var SavedAlwaysShowFocus = app.alwaysShowFocus ;
-% app.alwaysShowFocus  = true ;
-% "app.alwaysShowFocus  = SavedAlwaysShowFocus ; "
-
-\startJSpreamble RuntimeHighlightHack used now
-    var SavedHighlightState = app.runtimeHighlight ;
-    var SavedFocusRectState = app.focusRect ;
-    app.runtimeHighlight = false ;
-    app.focusRect        = true ;
-    this.setAction("WillClose",
-        "app.runtimeHighlight = SavedHighlightState ; " +
-        "app.focusRect        = SavedFocusRectState ; "
-    ) ;
-\stopJSpreamble
-
-\endinput
diff --git a/tex/context/base/mkiv/java-imp-steps.mkiv b/tex/context/base/mkiv/java-imp-steps.mkiv
new file mode 100644
index 000000000..3990e4d7a
--- /dev/null
+++ b/tex/context/base/mkiv/java-imp-steps.mkiv
@@ -0,0 +1,123 @@
+%D \module
+%D   [       file=java-imp-steps, % was: java-stp
+%D        version=2004.03.15,
+%D          title=\CONTEXT\ JavaScript Macros,
+%D       subtitle=Stepping,
+%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.
+
+% we define ocglist global, otherwise we quickly run into a memory hog (even
+% out of memory in a 512 Meg machine)
+
+% we cannot use doc_visited[this.pageNum] instead of doc_currentstep because
+% of some funny side effect (i.e. dup or so)
+
+% todo: test with later as we do autoinsert now
+
+\startJSpreamble Steps used now
+
+var doc_ocglist     = this.getOCGs() ;
+var doc_stepname    = "step" ;
+var doc_currentstep =  0 ;
+var doc_maxstep     = 50 ;
+var doc_visited     = new Array() ;
+var doc_busy        = new Array() ;
+
+function SetupStepper(layername,laststep) {
+    doc_stepname = layername ;
+    doc_maxstep  = laststep ;
+    for (var i=0; i<=this.numPages; i++) {
+        doc_visited[i] = 0 ;
+        doc_busy[i] = 0 ;
+    }
+}
+
+for (var i=0; i<=this.numPages; i++) {
+    doc_visited[i] = 0 ;
+    doc_busy[i] = 0 ;
+}
+
+function GetOCG(name) {
+    for (var i=0; i < doc_ocglist.length; i++) {
+        if (doc_ocglist[i].name == name) {
+            return doc_ocglist[i] ;
+        }
+    }
+    return null ;
+}
+
+function CheckBusy() {
+     var ocg = GetOCG("step:busy") ;
+     if (ocg != null) {
+         if (doc_visited[this.pageNum]==0) {
+             ocg.state = true ;
+         } else {
+             if (doc_visited[this.pageNum]<doc_busy[this.pageNum]) {
+                 ocg.state = true ;
+             } else {
+                 ocg.state = false ;
+             }
+         }
+     }
+}
+
+function SetStepper(maxstep,state) {
+    for (var i=1; i<=maxstep; i++) {
+        try {
+            var ocg = GetOCG(doc_stepname + ':' + String(i)) ;
+            if (ocg != null) {
+                ocg.state = state ;
+            }
+        } catch (e) {
+            return ;
+        }
+    }
+}
+
+function CheckStepper(maxsteps) {
+    SetStepper(doc_visited[this.pageNum], true) ;
+    doc_busy[this.pageNum] = Number(maxsteps) ;
+    doc_currentstep = doc_visited[this.pageNum] ;
+    CheckBusy() ;
+}
+
+function ResetStepper() {
+    SetStepper(doc_maxstep, false) ;
+    doc_currentstep = 0 ;
+}
+
+function InvokeStepper() {
+    try {
+        if (doc_currentstep<doc_busy[this.pageNum]) {
+            doc_currentstep += 1 ;
+            doc_visited[this.pageNum] = doc_currentstep ;
+            var ocg = GetOCG(doc_stepname + ':' + String(doc_currentstep)) ;
+            if (ocg != null) {
+                ocg.state = true ;
+            }
+        } else {
+            if (this.pageNum+1==this.numPages) {
+                this.pageNum  = 0 ;
+            } else {
+                this.pageNum += 1 ;
+            }
+        }
+        CheckBusy() ;
+    } catch (e) {
+        return ;
+    }
+}
+
+\stopJSpreamble
+
+% \definereference [SetupStepper]  [JS(SetupStepper{step,50})]
+% \definereference [ResetStepper]  [JS(ResetStepper)]
+% \definereference [CheckStepper]  [JS(CheckStepper{\StepCounter})]
+% \definereference [InvokeStepper] [JS(InvokeStepper)]
+
+\endinput
diff --git a/tex/context/base/mkiv/java-imp-stp.mkiv b/tex/context/base/mkiv/java-imp-stp.mkiv
deleted file mode 100644
index 8ac5d58b8..000000000
--- a/tex/context/base/mkiv/java-imp-stp.mkiv
+++ /dev/null
@@ -1,123 +0,0 @@
-%D \module
-%D   [       file=java-stp,
-%D        version=2004.03.15,
-%D          title=\CONTEXT\ JavaScript Macros,
-%D       subtitle=Stepping,
-%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.
-
-% we define ocglist global, otherwise we quickly run into a memory hog (even
-% out of memory in a 512 Meg machine)
-
-% we cannot use doc_visited[this.pageNum] instead of doc_currentstep because
-% of some funny side effect (i.e. dup or so)
-
-% todo: test with later as we do autoinsert now
-
-\startJSpreamble Steps used now
-
-var doc_ocglist     = this.getOCGs() ;
-var doc_stepname    = "step" ;
-var doc_currentstep =  0 ;
-var doc_maxstep     = 50 ;
-var doc_visited     = new Array() ;
-var doc_busy        = new Array() ;
-
-function SetupStepper(layername,laststep) {
-    doc_stepname = layername ;
-    doc_maxstep  = laststep ;
-    for (var i=0; i<=this.numPages; i++) {
-        doc_visited[i] = 0 ;
-        doc_busy[i] = 0 ;
-    }
-}
-
-for (var i=0; i<=this.numPages; i++) {
-    doc_visited[i] = 0 ;
-    doc_busy[i] = 0 ;
-}
-
-function GetOCG(name) {
-    for (var i=0; i < doc_ocglist.length; i++) {
-        if (doc_ocglist[i].name == name) {
-            return doc_ocglist[i] ;
-        }
-    }
-    return null ;
-}
-
-function CheckBusy() {
-     var ocg = GetOCG("step:busy") ;
-     if (ocg != null) {
-         if (doc_visited[this.pageNum]==0) {
-             ocg.state = true ;
-         } else {
-             if (doc_visited[this.pageNum]<doc_busy[this.pageNum]) {
-                 ocg.state = true ;
-             } else {
-                 ocg.state = false ;
-             }
-         }
-     }
-}
-
-function SetStepper(maxstep,state) {
-    for (var i=1; i<=maxstep; i++) {
-        try {
-            var ocg = GetOCG(doc_stepname + ':' + String(i)) ;
-            if (ocg != null) {
-                ocg.state = state ;
-            }
-        } catch (e) {
-            return ;
-        }
-    }
-}
-
-function CheckStepper(maxsteps) {
-    SetStepper(doc_visited[this.pageNum], true) ;
-    doc_busy[this.pageNum] = Number(maxsteps) ;
-    doc_currentstep = doc_visited[this.pageNum] ;
-    CheckBusy() ;
-}
-
-function ResetStepper() {
-    SetStepper(doc_maxstep, false) ;
-    doc_currentstep = 0 ;
-}
-
-function InvokeStepper() {
-    try {
-        if (doc_currentstep<doc_busy[this.pageNum]) {
-            doc_currentstep += 1 ;
-            doc_visited[this.pageNum] = doc_currentstep ;
-            var ocg = GetOCG(doc_stepname + ':' + String(doc_currentstep)) ;
-            if (ocg != null) {
-                ocg.state = true ;
-            }
-        } else {
-            if (this.pageNum+1==this.numPages) {
-                this.pageNum  = 0 ;
-            } else {
-                this.pageNum += 1 ;
-            }
-        }
-        CheckBusy() ;
-    } catch (e) {
-        return ;
-    }
-}
-
-\stopJSpreamble
-
-% \definereference [SetupStepper]  [JS(SetupStepper{step,50})]
-% \definereference [ResetStepper]  [JS(ResetStepper)]
-% \definereference [CheckStepper]  [JS(CheckStepper{\StepCounter})]
-% \definereference [InvokeStepper] [JS(InvokeStepper)]
-
-\endinput
diff --git a/tex/context/base/mkiv/java-imp-videoplayer.mkiv b/tex/context/base/mkiv/java-imp-videoplayer.mkiv
new file mode 100644
index 000000000..beda499a7
--- /dev/null
+++ b/tex/context/base/mkiv/java-imp-videoplayer.mkiv
@@ -0,0 +1,82 @@
+%D \module
+%D   [       file=java-imp-videoplayer,
+%D        version=2009.12.31,
+%D          title=\CONTEXT\ JavaScript Macros,
+%D       subtitle=Shockwave Support,
+%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 As part of the interaction manual writing this code was moved here. It's
+%D kind of obsolete as shockwave is obsolete.
+
+% using videoplayer.swf from adobe or strobemediaplayback.swf from sourceforge:
+
+\startluaparameterset[shockwave:display]
+    toolbar  = true,
+ -- preview  = "somefile",
+    open     = "click",
+    close    = "focus",
+\stopluaparameterset
+
+\startJSpreamble shockwave used now
+
+    function StartShockwave(label) {
+        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
+        if (rm.activated) {
+            rm.callAS("multimedia_play") ;
+        } else {
+            rm.activated = true ;
+        }
+    }
+
+    function StopShockwave(label) {
+        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
+        if (rm.activated) {
+            rm.callAS("multimedia_pause") ;
+            rm.callAS("multimedia_rewind") ;
+        }
+    }
+
+    function RewindShockwave(label) {
+        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
+        if (rm.activated) {
+            rm.callAS("multimedia_rewind") ;
+        }
+    }
+
+    function PauseShockwave(label) {
+        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
+        if (rm.activated) {
+            rm.callAS("multimedia_pause") ;
+        }
+    }
+
+\stopJSpreamble
+
+\definereference[StartShockwave] [JS(StartShockwave)]
+\definereference[StopShockwave]  [JS(StopShockwave)]
+\definereference[RewindShockwave][JS(RewindShockwave)]
+\definereference[PauseShockwave] [JS(PauseShockwave)]
+
+\unprotect
+
+\doglobal \useexternalfigure
+  [shockwave]
+  [videoplayer.swf]
+  [\c!arguments=\luaparameterset{shockwave:arguments}{source="\externalfigureparameter\v!file"},
+   \c!resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}},
+   \c!display=shockwave:display]
+
+% \doglobal \useexternalfigure
+%   [shockwave]
+%   [strobemediaplayback.swf]
+%   [arguments=\luaparameterset{shockwave:arguments}{src="\externalfigureparameter\v!file"},
+%    resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}},
+%    display=shockwave:display]
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/java-imp-vplayer.mkiv b/tex/context/base/mkiv/java-imp-vplayer.mkiv
new file mode 100644
index 000000000..4ed08cad6
--- /dev/null
+++ b/tex/context/base/mkiv/java-imp-vplayer.mkiv
@@ -0,0 +1,105 @@
+%D \module
+%D   [       file=java-imp-vplayer,
+%D        version=2009.12.31,
+%D          title=\CONTEXT\ JavaScript Macros,
+%D       subtitle=Shockwave Support,
+%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 As part of the interaction manual writing this code was moved here. It's
+%D kind of obsolete as shockwave is obsolete. Anywaym, here's how it works.
+%D One can actually set all kind of properties but let's not waste time on
+%D that. Maybe some day \PDF\ will have proper native video support.
+%D
+%D \starttyping
+%D \starttext
+%D
+%D     \useJSscripts[vplayer]
+%D
+%D     \setupinteraction
+%D       [state=start]
+%D
+%D     \externalfigure
+%D       [shockwave]
+%D       [frame=on,
+%D        width=480pt,
+%D        height=270pt,
+%D       %file=mathematics.mp4, % Hollie McNish, Martin Pyper & Jules Buckley (Metropole Orchestra)
+%D        file=bathtub.mp4,     % Jacob Collier & Becca Stevens
+%D        label=foo]
+%D
+%D     \goto{START} [JS(StartShockwave{foo})]
+%D     \goto{REWIND}[JS(RewindShockwave{foo})]
+%D     \goto{PAUSE} [JS(PauseShockwave{foo})]
+%D     \goto{STOP}  [JS(StopShockwave{foo})]
+%D
+%D \stoptext
+%D \stoptyping
+
+% using vplayer9.swf from ctan:
+
+\startluaparameterset[shockwave:display]
+    toolbar  = true,
+ -- preview  = "somefile",
+    open     = "click",
+    close    = "focus",
+\stopluaparameterset
+
+\startJSpreamble shockwave used now
+
+    function StartShockwave(label) {
+        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
+        if (rm.activated) {
+            // ok
+        } else {
+            rm.activated = true ;
+        }
+        rm.callAS("rewind") ;
+        rm.callAS("playPause") ;
+    }
+
+    function StopShockwave(label) {
+        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
+        if (rm.activated) {
+            rm.callAS("pause") ;
+            rm.callAS("rewind") ;
+        }
+    }
+
+    function RewindShockwave(label) {
+        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
+        if (rm.activated) {
+            rm.callAS("rewind") ;
+        }
+    }
+
+    function PauseShockwave(label) {
+        var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ;
+        if (rm.activated) {
+            rm.callAS("playPause") ;
+        }
+    }
+
+\stopJSpreamble
+
+\definereference[StartShockwave] [JS(StartShockwave)]
+\definereference[StopShockwave]  [JS(StopShockwave)]
+\definereference[RewindShockwave][JS(RewindShockwave)]
+\definereference[PauseShockwave] [JS(PauseShockwave)]
+
+\unprotect
+
+\doglobal \useexternalfigure
+  [shockwave]
+  [vplayer9.swf]
+ %[arguments=\luaparameterset{shockwave:arguments}{src="\externalfigureparameter\v!file",source="\externalfigureparameter\v!file"},
+  [\c!arguments=\luaparameterset{shockwave:arguments}{source="\externalfigureparameter\v!file",autoPlay=true},
+   \c!resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}},
+   \c!display=shockwave:display]
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/java-ini.mkiv b/tex/context/base/mkiv/java-ini.mkiv
index 1a131d9da..95c9c5220 100644
--- a/tex/context/base/mkiv/java-ini.mkiv
+++ b/tex/context/base/mkiv/java-ini.mkiv
@@ -38,7 +38,6 @@
 %D \goto{calculate total}[Sum(1.5,2.3)]
 %D \stoptyping
 
-
 %D \macros
 %D   {startJScode}
 %D
@@ -162,4 +161,12 @@
 \def\java_use_preamble[#1]%
   {\clf_usejavascriptpreamble{#1}}% so this one comes later
 
+%D Here:
+
+\definefilesynonym[java-imp-fld.mkiv] [java-imp-fields.mkiv]
+\definefilesynonym[java-imp-stp.mkiv] [java-imp-steps.mkiv]
+\definefilesynonym[java-imp-fil.mkiv] [java-imp-print.mkiv]
+\definefilesynonym[java-imp-rhh.mkiv] [java-imp-highlight.mkiv]
+\definefilesynonym[java-imp-exa.mkiv] [java-imp-example.mkiv]
+
 \protect \endinput
diff --git a/tex/context/base/mkiv/lang-dis.lua b/tex/context/base/mkiv/lang-dis.lua
index 1e46cbd36..a45e87e9c 100644
--- a/tex/context/base/mkiv/lang-dis.lua
+++ b/tex/context/base/mkiv/lang-dis.lua
@@ -181,7 +181,7 @@ function languages.nofflattened()
     return wiped -- handy for testing
 end
 
--- experiment
+-- experiment: for now not in not in export mode!
 
 local flatten = languages.flatten
 local getlist = nodes.getlist
@@ -196,6 +196,7 @@ function nodes.handlers.flatten(head,where)
 end
 
 directives.register("hyphenator.flatten",function(v)
+    -- use with care
     setaction("processors","nodes.handlers.flatten",v)
     setaction("contributers","nodes.handlers.flattenline",v)
 end)
diff --git a/tex/context/base/mkiv/lang-mis.mkiv b/tex/context/base/mkiv/lang-mis.mkiv
index f2c837f54..3ec29a782 100644
--- a/tex/context/base/mkiv/lang-mis.mkiv
+++ b/tex/context/base/mkiv/lang-mis.mkiv
@@ -145,7 +145,11 @@
 %D modules these can be tuned by a setup command. Watch the (maybe) better looking
 %D compound hyphen.
 
-\ifx\compoundhyphen    \undefined \unexpanded\def\compoundhyphen    {\hbox{-\kern-.25ex-}} \fi
+% hm why ex
+
+\ifx\compoundhyphen    \undefined
+    \unexpanded\def\compoundhyphen {\hbox{-\kern-.10775\emwidth-}} % .25\exheight
+\fi
 
 %D The last two variables are needed for subsentences |<|like this one|>| which we
 %D did not yet mention. We want to enable breaking but at the same time don't want
diff --git a/tex/context/base/mkiv/lpdf-pde.lua b/tex/context/base/mkiv/lpdf-pde.lua
index 819143a3b..d7aa9f40c 100644
--- a/tex/context/base/mkiv/lpdf-pde.lua
+++ b/tex/context/base/mkiv/lpdf-pde.lua
@@ -52,7 +52,13 @@ local setmetatableindex = table.setmetatableindex
 local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
 local P, C, S, R, Ct, Cc, V, Carg, Cs, Cf, Cg = lpeg.P, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cc, lpeg.V, lpeg.Carg, lpeg.Cs, lpeg.Cf, lpeg.Cg
 
-if not lpdf then require("lpdf-aux") end
+if not lpdf then
+    require("lpdf-aux")
+end
+
+if not (number and number.dimenfactors) then
+    require("util-dim")
+end
 
 local epdf              = pdfe
       lpdf              = lpdf or { }
@@ -343,12 +349,12 @@ end
 
 function resolvers.javascripts(document)
     local Names = document.Catalog.Names
-    return getnames(document,Names and Names.JS)
+    return getnames(document,Names and Names.JavaScript)
 end
 
 function resolvers.widgets(document)
-    local Names = document.Catalog.Names
-    return getnames(document,Names and Names.AcroForm)
+    local Names = document.Catalog.AcroForm
+    return Names and Names.Fields
 end
 
 function resolvers.embeddedfiles(document)
diff --git a/tex/context/base/mkiv/lpdf-swf.lua b/tex/context/base/mkiv/lpdf-swf.lua
index 0ac107f8b..7d76efc73 100644
--- a/tex/context/base/mkiv/lpdf-swf.lua
+++ b/tex/context/base/mkiv/lpdf-swf.lua
@@ -65,7 +65,10 @@ local function insertswf(spec)
     local preview   = checkedkey(display,"preview","string")
     local toolbar   = checkedkey(display,"toolbar","boolean")
 
-    local embeddedreference = codeinjections.embedfile { file = filename }
+    local embeddedreference = codeinjections.embedfile {
+        file     = filename,
+        compress = false,
+    }
 
     local flash = pdfdictionary {
         Subtype   = pdfconstant("RichMediaConfiguration"),
@@ -122,6 +125,7 @@ local function insertswf(spec)
                 file     = fullname,
                 usedname = usedname,
                 keepdir  = true,
+                compress = false,
             }
             names[#names+1] = pdfstring(filename)
             names[#names+1] = embeddedreference
diff --git a/tex/context/base/mkiv/lpdf-wid.lua b/tex/context/base/mkiv/lpdf-wid.lua
index 5793fc723..a929ed2ce 100644
--- a/tex/context/base/mkiv/lpdf-wid.lua
+++ b/tex/context/base/mkiv/lpdf-wid.lua
@@ -267,9 +267,13 @@ function codeinjections.embedfile(specification)
     local keepdir  = specification.keepdir -- can change
     local usedname = specification.usedname
     local filetype = specification.filetype
+    local compress = specification.compress
     if filename == "" then
         filename = nil
     end
+    if compress == nil then
+        compress = true
+    end
     if data then
         local r = filestreams[hash]
         if r == false then
@@ -324,7 +328,7 @@ function codeinjections.embedfile(specification)
         specification.data = true -- signal that still data but already flushed
     else
         local foundname = specification.foundname or filename
-        f = pdfflushstreamfileobject(foundname,a)
+        f = pdfflushstreamfileobject(foundname,a,compress)
     end
     local d = pdfdictionary {
         Type = pdfconstant("Filespec"),
@@ -663,6 +667,7 @@ local function insertrendering(specification)
             descriptor.EF = codeinjections.embedfile {
                 file     = filename,
                 mimetype = mimetype, -- yes or no
+                compress = false,
             }
         end
         local clip = pdfdictionary {
diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua
index 5491078f3..66c08a76a 100644
--- a/tex/context/base/mkiv/math-ini.lua
+++ b/tex/context/base/mkiv/math-ini.lua
@@ -39,13 +39,6 @@ local mathematics           = mathematics
 mathematics.extrabase       = fonts.privateoffsets.mathextrabase -- here we push some virtuals
 mathematics.privatebase     = fonts.privateoffsets.mathbase      -- here we push the ex
 
-fonts.privateoffsets = {
-    textbase      = 0xF0000, -- used for hidden (opentype features)
-    textextrabase = 0xFD000, -- used for visible by name
-    mathextrabase = 0xFE000, -- used for visible by code
-    mathbase      = 0xFF000, -- used for hidden (virtual math)
-}
-
 local unsetvalue            = attributes.unsetvalue
 local allocate              = utilities.storage.allocate
 local chardata              = characters.data
diff --git a/tex/context/base/mkiv/pack-mrl.mkiv b/tex/context/base/mkiv/pack-mrl.mkiv
index 85aa3ad04..bef790536 100644
--- a/tex/context/base/mkiv/pack-mrl.mkiv
+++ b/tex/context/base/mkiv/pack-mrl.mkiv
@@ -39,7 +39,7 @@
 \installsimplecommandhandler \??blackrules {blackrules}
 
 \unexpanded\def\blackrule
-  {\hbox\bgroup
+  {\hpack\bgroup
    \doifelsenextoptionalcs\pack_black_rule_pickup\pack_black_rule_indeed}
 
 \def\pack_black_rule_pickup[#1]%
@@ -99,7 +99,7 @@
 %D would probably have taken more tokens.
 
 \unexpanded\def\blackrules % probably never used
-  {\hbox\bgroup
+  {\hpack\bgroup
    \doifelsenextoptionalcs\pack_black_rules_pickup\pack_black_rules_indeed}
 
 \def\pack_black_rules_pickup[#1]%
@@ -121,23 +121,25 @@
      \fi
    \fi
    \useblackrulesstyleandcolor\c!style\c!color
-   \edef\brule
-     {\ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname
-        \lastnamedcs
-      \else
-        \vrule
-      \fi}%
-   \dorecurse\scratchcounter % a typical case of where we can use a simple loop
-     {\brule
-        \s!width \scratchwidth
-        \s!height\scratchheight
-        \s!depth \scratchdepth
-      \ifzeropt\scratchdistance\else
-        \hskip\scratchdistance
-      \fi}%
+   % a typical case of where we can use a simple loop or even a leaders
+   \dorecurse\scratchcounter\pack_black_rules_step
    \unskip
    \egroup}
 
+\def\pack_black_rules_step
+  {\ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname
+     \lastnamedcs
+   \else
+     \vrule
+   \fi
+   \s!width \scratchwidth
+   \s!height\scratchheight
+   \s!depth \scratchdepth
+   \relax
+   \ifzeropt\scratchdistance\else
+     \hskip\scratchdistance
+   \fi}
+
 \installcorenamespace{blackruletype}
 
 \setvalue{\??blackruletype mp}%
@@ -578,14 +580,14 @@
   {\page[\v!preference] % interferes
    \directtextrulesparameter\c!before\relax
    \blank[\v!samepage,\v!nowhite]%
-   \pack_textrule_with_text{#1}%
+   \pack_textrule_with_text_yes{#1}%
    \blank[\v!samepage,\v!nowhite]%
    \directtextrulesparameter\c!inbetween\relax
    \endgraf}
 
 \setvalue{\??textrulealternatives\v!bottom}#1%
   {\blank[\v!samepage,\v!nowhite]%
-   \pack_textrule_following{#1}%
+   \pack_textrule_following_yes{#1}%
    \blank[\v!samepage,\v!nowhite]%
    \directtextrulesparameter\c!after\relax
    \page[\v!preference]}
@@ -593,14 +595,15 @@
 \setvalue{\??textrulealternatives\v!middle}#1%
   {\blank[\v!samepage,\v!nowhite]%
    \directtextrulesparameter\c!inbetween\relax
-   \pack_textrule_following{#1}%
+   \pack_textrule_following_yes{#1}%
    \blank[\v!samepage,\v!nowhite]%
    \directtextrulesparameter\c!inbetween\relax
    \page[\v!preference]}
 
-\def\pack_textrule_with_text#1%
-  {\bgroup
-   \setbox\scratchbox\hbox to \availablehsize
+\def\pack_textrule_with_text_yes#1%
+  {\noindent % this will force side floats to be calculated
+   \bgroup
+   \setbox\scratchbox\hpack to \availablehsize
      {\scratchwidth \directtextrulesparameter\c!rulethickness\relax
       \scratchheight\dimexpr .5\exheight+.5\scratchwidth\relax
       \scratchdepth \dimexpr-.5\exheight+.5\scratchwidth\relax
@@ -611,19 +614,41 @@
                #1%
                \hskip\leftmargindistance}}
            {\color[\directtextrulesparameter\c!rulecolor]
-              {\vrule\s!height\scratchheight\s!depth\scratchdepth\s!width\directtextrulesparameter\c!width}%
+              {\vrule
+                 \s!height\scratchheight
+                 \s!depth \scratchdepth
+                 \s!width \directtextrulesparameter\c!width}%
             \hbox spread 2\dimexpr\directtextrulesparameter\c!distance\relax
               {\hss
                \usetextrulesstyleandcolor\c!style\c!color
                \strut#1%
                \hss}}}%
       \color[\directtextrulesparameter\c!rulecolor]
-        {\leaders\hrule\s!height\scratchheight\s!depth\scratchdepth\hfill}}%
+        {\leaders\hrule
+           \s!height\scratchheight
+           \s!depth \scratchdepth
+           \hfill}}%
    \ht\scratchbox\strutht
    \dp\scratchbox\strutdp
-   \noindent\box\scratchbox
+   \box\scratchbox
+  %\carryoverpar
    \egroup}
 
+\def\pack_textrule_with_text_nop#1%
+  {\ifhmode
+     \endgraf
+   \fi
+   \doifelse{\directtextrulesparameter\c!depthcorrection}\v!on
+     \pack_textrule_correct_depth_yes
+     \pack_textrule_correct_depth_nop
+   \nointerlineskip
+   \noindent\vpack % was \dontleavehmode
+     {\color[\directtextrulesparameter\c!rulecolor]
+        {\hrule
+           \s!depth \directtextrulesparameter\c!rulethickness
+           \s!height\zeropoint
+           \s!width \availablehsize}}}
+
 \def\pack_textrule_correct_depth_yes
   {\vskip\dimexpr
      \strutdp +.5\exheight
@@ -643,15 +668,9 @@
 
 \def\pack_textrule_following#1%
   {\doifelsenothing{#1}
-     {\ifhmode
-        \endgraf
-      \fi
-      \doifelse{\directtextrulesparameter\c!depthcorrection}\v!on\pack_textrule_correct_depth_yes\pack_textrule_correct_depth_nop
-      \nointerlineskip
-      \noindent\vbox % was \dontleavehmode
-        {\color[\directtextrulesparameter\c!rulecolor]
-           {\hrule\s!depth\directtextrulesparameter\c!rulethickness\s!height\zeropoint\s!width\availablehsize}}}
-     {\pack_textrule_with_text{#1}}%
+     \pack_textrule_with_text_nop
+     \pack_textrule_with_text_yes
+     {#1}%
    \ifvmode
      \prevdepth\zeropoint
    \fi}
diff --git a/tex/context/base/mkiv/page-sid.mkiv b/tex/context/base/mkiv/page-sid.mkiv
index 812196e6f..303b77af2 100644
--- a/tex/context/base/mkiv/page-sid.mkiv
+++ b/tex/context/base/mkiv/page-sid.mkiv
@@ -81,6 +81,9 @@
 
 \newdimen       \d_page_sides_progression
 
+\newcount       \c_page_sides_m_of_lines
+\newconditional \c_page_sides_delayed
+
 \newif          \iftracesidefloats % public (might change)
 
 %D Defaults:
@@ -764,7 +767,7 @@
    \prevdepth\strutdp}
   %\ignoreparskip}
 
-\def\page_sides_handle_float#1% grid (4) is rather experimental
+\def\page_sides_handle_float#1%
   {\page_sides_initialize_checker
    \page_sides_check_horizontal_skips
    \page_sides_check_vertical_skips
@@ -776,8 +779,11 @@
    \page_sides_apply_vertical_shift
    \page_sides_analyse_space
    \ifconditional\c_page_floats_room
+     \global\setfalse\c_page_sides_delayed
      % we're ok
    \else
+     \global\settrue\c_page_sides_delayed
+     \global\c_page_sides_m_of_lines\c_page_sides_n_of_lines
      \ifcase\c_page_sides_page_method
        \page_otr_fill_and_eject_page
      \or
@@ -785,11 +791,13 @@
      \else
        \page_otr_fill_and_eject_page
      \fi
+     \global\c_page_sides_n_of_lines\c_page_sides_m_of_lines
      \page_sides_analyse_space
     %\page_sides_inject_before
      \page_sides_inject_dummy_lines
    \fi
    \page_sides_place_float
+   \global\setfalse\c_page_sides_delayed
    \page_sides_check_floats_reset
    \page_sides_wrapup}
 
@@ -797,8 +805,7 @@
   {% we need to do this aftergroup
    \aftergroup\par
    \aftergroup\ignoreparskip
-   \aftergroup\ignorespaces
-   }
+   \aftergroup\ignorespaces}
 
 \def\page_sides_check_floats_indeed
   {\page_sides_analyse_progress
@@ -857,6 +864,10 @@
 
 \unexpanded\def\page_sides_check_floats_set
   {\edef\p_sidethreshold{\floatparameter\c!sidethreshold}%
+   \ifconditional\c_page_sides_delayed
+     % For Alan's hanging right float that moved to the next page.
+     \d_page_sides_progress\zeropoint
+   \fi
    \ifx\p_sidethreshold\v!old
      \d_page_sides_progression\dimexpr\d_page_sides_progress+\strutht-\roundingeps\relax
      \c_page_sides_n_of_hang\d_page_sides_progression
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 7d9a44566..31155292e 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 5a886244b..b1227d969 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/strc-ref.lua b/tex/context/base/mkiv/strc-ref.lua
index 0acfab7f7..8b0c5467e 100644
--- a/tex/context/base/mkiv/strc-ref.lua
+++ b/tex/context/base/mkiv/strc-ref.lua
@@ -1496,7 +1496,7 @@ local function identify_inner(set,var,prefix,collected,derived)
         end
     end
     -- we now ignore the split prefix and treat the whole inner as a potential
-    -- referenice into the global list
+    -- reference into the global list
     local i = collected[prefix]
     if i then
         i = i[inner]
@@ -1552,6 +1552,17 @@ local function identify_outer(set,var,i)
             end
             return v
         end
+-- weird too (we really need to check how this table is build
+        local v = identify_inner(set,var,var.outer,external)
+        if v then
+            v.kind = "outer with inner"
+            set.external = true
+            if trace_identifying then
+                report_identify_outer(set,v,i,"2c")
+            end
+            return v
+        end
+--
         -- somewhat rubish: we use outer as first step in the externals table so it makes no
         -- sense to have it as prefix so the next could be an option
         local external = external[""]
@@ -2556,10 +2567,19 @@ local function referencepagestate(position,detail,spread)
     if not actions then
         return 0
     else
-        if not actions.pagestate then
+        local pagestate = actions.pagestate
+        for i=1,#actions do
+            local a = actions[i]
+            if a.outer then
+                pagestate = 0
+                actions.pagestate = pagestate
+                break
+            end
+        end
+        if not pagestate then
             references.analyze(actions,position,spread) -- delayed unless explicitly asked for
+            pagestate = actions.pagestate
         end
-        local pagestate = actions.pagestate
         if detail then
             return pagestate
         elseif pagestate == 4 then
diff --git a/tex/context/base/mkiv/symb-imp-fontawesome.mkiv b/tex/context/base/mkiv/symb-imp-fontawesome.mkiv
index cae2e506b..13a8fc678 100644
--- a/tex/context/base/mkiv/symb-imp-fontawesome.mkiv
+++ b/tex/context/base/mkiv/symb-imp-fontawesome.mkiv
@@ -749,8 +749,27 @@
 
 \stopsymbolset
 
+
+\definefontsynonym [FontAwesomeBrands]  [file:fontawesome5brandsregular400.otf]
+\definefontsynonym [FontAwesomeRegular] [file:fontawesome5freeregular400.otf]
+\definefontsynonym [FontAwesomeSolid]   [file:fontawesome5freesolid900.otf]
+
+\startsymbolset [fontawesome-brands] [font=FontAwesomeBrands]
+    % Font Awesome Brands
+\stopsymbolset
+
+\startsymbolset [fontawesome-regular] [font=FontAwesomeRegular]
+    % Font Awesome Regular
+\stopsymbolset
+
+\startsymbolset [fontawesome-solid] [font=FontAwesomeSolid]
+    % Font Awesome Solid
+\stopsymbolset
+
 \continueifinputfile{symb-imp-fontawesome.mkiv}
 
+\usemodule[article-basic]
+
 \starttext
 
   % \usesymbols[fontawesome]
@@ -760,6 +779,18 @@
   % \symbol[fontawesome][angle right]
   % \symbol[fontawesome][angle_right]
 
-    \showsymbolset[fontawesome]
+  % \showsymbolset[fontawesome]
+
+    \startnamedsection [title] [title={Font Awesome Brands}]
+        \showsymbolset [fontawesome-brands]
+    \stopnamedsection
+
+    \startnamedsection [title] [title={Font Awesome Regular}]
+        \showsymbolset [fontawesome-regular]
+    \stopnamedsection
+
+    \startnamedsection [title] [title={Font Awesome Solid}]
+        \showsymbolset [fontawesome-solid]
+    \stopnamedsection
 
 \stoptext
diff --git a/tex/context/base/mkiv/tabl-ntb.mkiv b/tex/context/base/mkiv/tabl-ntb.mkiv
index 54eca6cd3..ca3d78800 100644
--- a/tex/context/base/mkiv/tabl-ntb.mkiv
+++ b/tex/context/base/mkiv/tabl-ntb.mkiv
@@ -1161,13 +1161,11 @@
 
 \def\tabl_ntb_row_stop_boxed
   {% \noindent % no, else double leftskip in narrower
-   \normalexpanded
-     {\t_tabl_ntb
-        {\the\t_tabl_ntb
-         % no need for init
-         \tabl_ntb_row_align_start
-         \the\t_tabl_ntb_row
-         \tabl_ntb_row_align_stop}}}
+   \etoksapp\t_tabl_ntb
+     {% no need for init
+      \tabl_ntb_row_align_start
+      \the\t_tabl_ntb_row
+      \tabl_ntb_row_align_stop}}
 
 \def\tabl_ntb_row_stop_split
   {\ifcsname\??naturaltableset\m_tabl_tbl_level:\c!y++\the\c_tabl_ntb_current_row\endcsname
@@ -1177,13 +1175,11 @@
    \fi}
 
 \def\tabl_ntb_row_stop_split_nop
-  {\normalexpanded
-     {\t_tabl_ntb
-        {\the\t_tabl_ntb
-         \tabl_ntb_row_align_reset
-         \tabl_ntb_row_align_start
-         \the\t_tabl_ntb_row
-         \tabl_ntb_row_align_stop}}}
+  {\etoksapp\t_tabl_ntb
+     {\tabl_ntb_row_align_reset
+      \tabl_ntb_row_align_start
+      \the\t_tabl_ntb_row
+      \tabl_ntb_row_align_stop}}
 
 \def\tabl_ntb_row_stop_split_yes
   {\begingroup
@@ -1192,13 +1188,11 @@
    \xdef\m_tabl_ntb_after_split {\naturaltablelocalparameter\c!after}% to be checked
    \xdef\m_tabl_ntb_same_page   {\naturaltablelocalparameter\c!samepage}%
    \endgroup
-   \normalexpanded
-     {\t_tabl_ntb
-        {\the\t_tabl_ntb
-         \tabl_ntb_row_align_set{\m_tabl_ntb_before_split}{\m_tabl_ntb_after_split}{\m_tabl_ntb_same_page}%
-         \tabl_ntb_row_align_start
-         \the\t_tabl_ntb_row
-         \tabl_ntb_row_align_stop}}}
+   \etoksapp\t_tabl_ntb
+     {\tabl_ntb_row_align_set{\m_tabl_ntb_before_split}{\m_tabl_ntb_after_split}{\m_tabl_ntb_same_page}%
+      \tabl_ntb_row_align_start
+      \the\t_tabl_ntb_row
+      \tabl_ntb_row_align_stop}}
 
 \unexpanded\def\tabl_ntb_row_align_set#1#2#3%
   {\xdef\m_tabl_ntb_before_split{#1}%
@@ -1225,12 +1219,10 @@
         \tabl_ntb_prelocate_error
       \fi}%
    \def\tabl_ntb_row_stop
-     {\normalexpanded
-        {\t_tabl_ntb
-           {\the\t_tabl_ntb
-            \tabl_ntb_row_align_start
-            \the\csname\??naturaltabletok\the\c_tabl_ntb_row\endcsname
-            \tabl_ntb_row_align_stop}}}%
+     {\etoksapp\t_tabl_ntb
+        {\tabl_ntb_row_align_start
+         \the\csname\??naturaltabletok\the\c_tabl_ntb_row\endcsname
+         \tabl_ntb_row_align_stop}}%
    \global\c_tabl_prelocated_rows#1\relax}
 
 \def\tabl_ntb_prelocate_okay
@@ -1344,37 +1336,23 @@
   {\global\advance\c_tabl_ntb_col\plusone
    \kern\d_tabl_ntb_columndistance}
 
-% \setvalue{\??naturaltablecell\the\c_tabl_ntb_none}#1#2%
-%   {\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
-%    \ifnum\scratchcounter>\zerocount
-%      \normalexpanded
-%        {\t_tabl_ntb_row
-%           {\the\t_tabl_ntb_row
-%            \tabl_ntb_span{\the\scratchcounter}%
-%            \tabl_ntb_plus}}%
-%    \fi}
-
 \setvalue{\??naturaltablecell\the\c_tabl_ntb_none}#1#2%
   {\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
    \ifnum\scratchcounter>\zerocount
-     \normalexpanded
-       {\t_tabl_ntb_row
-          {\the\t_tabl_ntb_row
-           \tabl_ntb_span{\the\scratchcounter}}}%
+     \etoksapp\t_tabl_ntb_row
+       {\tabl_ntb_span{\the\scratchcounter}}%
    \fi}
 
 \setvalue{\??naturaltablecell\the\c_tabl_ntb_cell}#1#2%
   {\toksapp\t_tabl_ntb_row{\tabl_ntb_pass #1 #2 }% space delimited -> less tokens
    \scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
    \ifnum\scratchcounter>\zerocount
-     \normalexpanded
-       {\t_tabl_ntb_row
-          {\the\t_tabl_ntb_row
-           \ifnum\scratchcounter=\plusone
-             \tabl_ntb_plus
-           \else
-             \tabl_ntb_skip{\the\scratchcounter}%
-           \fi}}%
+     \etoksapp\t_tabl_ntb_row
+        {\ifnum\scratchcounter=\plusone
+           \tabl_ntb_plus
+         \else
+           \tabl_ntb_skip{\the\scratchcounter}%
+         \fi}%
    \fi}
 
 \unexpanded\def\tabl_ntb_cell#1#2%
diff --git a/tex/context/base/mkiv/trac-log.lua b/tex/context/base/mkiv/trac-log.lua
index 297d053ab..83b81c9b0 100644
--- a/tex/context/base/mkiv/trac-log.lua
+++ b/tex/context/base/mkiv/trac-log.lua
@@ -405,6 +405,15 @@ if runningtex then
     setlogfile  = ignore
     settimedlog = ignore
 
+ -- settimedlog = function()
+ --     local localtime = os.localtime
+ --     local writeline = write_nl
+ --     write_nl = function(f,...)
+ --         writeline(f,localtime() .. " | " .. concat { ... })
+ --     end
+ --     settimedlog = ignore
+ -- end
+
 else
 
     local report_yes, subreport_yes, status_yes
diff --git a/tex/context/base/mkiv/util-sql-imp-sqlite.lua b/tex/context/base/mkiv/util-sql-imp-sqlite.lua
index 04d5ced3a..cf4a3a8b0 100644
--- a/tex/context/base/mkiv/util-sql-imp-sqlite.lua
+++ b/tex/context/base/mkiv/util-sql-imp-sqlite.lua
@@ -132,7 +132,6 @@ setmetatable(cache, {
 local f_preamble = formatters[ [[
 ATTACH `%s` AS `%s` ;
 PRAGMA `%s`.synchronous = normal ;
-PRAGMA journal_mode = truncate ;
 ]] ]
 
 local function execute(specification)
@@ -211,17 +210,19 @@ local function execute(specification)
         else
             local column = { }
             callback = function(data,nofcolumns,values,fields)
-                for i=0,nofcolumns-1 do
+                for i=1,nofcolumns do
                     local field
                     if keysdone then
-                        field = keys[i+1]
+                        field = keys[i]
                     else
                      -- field = get_list_item(fields,i)
-                        field = ffi_tostring(fields[i])
+                        field = ffi_tostring(fields[i-1])
                         keys[i+1] = field
                     end
-                 -- column[field] = get_list_item(values,i)
-                    column[field] = ffi_tostring(values[i])
+                    if field then
+                     -- column[field] = get_list_item(values,i)
+                        column[field] = ffi_tostring(values[i-1])
+                    end
                 end
                 nofrows  = nofrows + 1
                 keysdone = true
diff --git a/tex/context/fonts/mkiv/type-imp-plex.mkiv b/tex/context/fonts/mkiv/type-imp-plex.mkiv
index 99b099474..44334bcbd 100644
--- a/tex/context/fonts/mkiv/type-imp-plex.mkiv
+++ b/tex/context/fonts/mkiv/type-imp-plex.mkiv
@@ -14,10 +14,12 @@
 % Taco will make a special (more verbose) one for the ConTeXt journal! That setup will also have
 % adapted interline spacing matching the larger ascenders.
 
-% [IBMPlexMono|IBMPlexSans|IBMPlexSerif|IBMPlexSansCondensed]-[Thin|Light|Text||Medium|SemiBold|Bold|Extra].otf
-% [IBMPlexMono|IBMPlexSans|IBMPlexSerif|IBMPlexSansCondensed]-[Thin|Light|Text||Medium|SemiBold|Bold|Extra]Italic.otf
+%  thin, extralight, light, regular, text, medium, semibold, bold
 
-% [IBMPlexSans][Hebrew]-[Thin|Light|Text||Medium|SemiBold|Bold|].otf
+% [IBMPlexMono|IBMPlexSans|IBMPlexSerif|IBMPlexSansCondensed]-[Thin|ExtraLight|Light||Text|Medium|SemiBold|Bold].otf
+% [IBMPlexMono|IBMPlexSans|IBMPlexSerif|IBMPlexSansCondensed]-[Thin|ExtraLight|Light||Text|Medium|SemiBold|Bold]Italic.otf
+
+% [IBMPlexSans][Hebrew]-[Thin|Light||Text|Medium|SemiBold|Bold|].otf
 
 \loadtypescriptfile[bookman]
 
@@ -27,59 +29,69 @@
     \definetypescriptprefix [n:plexsans]        [IBMPlexSans]
     \definetypescriptprefix [n:plexmono]        [IBMPlexMono]
 
-    \definetypescriptprefix [n:plexserifnarrow] [IBMPlexSerif]
-    \definetypescriptprefix [n:plexsansnarrow]  [IBMPlexSansCondensed]
-    \definetypescriptprefix [n:plexmonnarrow]   [IBMPlexMono]
+    \definetypescriptprefix [n:narrowplexserif] [IBMPlexSerif]
+    \definetypescriptprefix [n:narrowplexsans]  [IBMPlexSansCondensed]
+    \definetypescriptprefix [n:narrowplexmono]  [IBMPlexMono]
 
     \definetypescriptprefix [f:plexserif]       [\s!default]
     \definetypescriptprefix [f:plexsans]        [\s!default]
     \definetypescriptprefix [f:plexmono]        [\s!none]
 
-    \definetypescriptprefix [f:plexserifnarrow] [\s!default]
-    \definetypescriptprefix [f:plexsansnarrow]  [\s!default]
-    \definetypescriptprefix [f:plexmononarrow]  [\s!none]
+    \definetypescriptprefix [f:narrowplexserif] [\s!default]
+    \definetypescriptprefix [f:narrowplexsans]  [\s!default]
+    \definetypescriptprefix [f:narrowplexmono]  [\s!none]
 
-    % [THIN|light|TEXT||medium|semibold|bold|extra]
+    % thin
 
-    \starttypescript [\s!sans,\s!serif,\s!mono] [plex-thin,plex-hairline] [\s!name]
+    \starttypescript [\s!sans,\s!serif,\s!mono] [plex-thin] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
         \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-thin]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-thinitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-text]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-text]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-light]      [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-light]      [\s!features=\typescriptprefix{f:plex\typescriptone}]
     \stoptypescript
 
-    % [thin|LIGHT|text||medium|semibold|bold|extra]
+    % extralight
+
+    \starttypescript [\s!sans,\s!serif,\s!mono] [plex-extralight] [\s!name]
+        \setups[\s!font:\s!fallback:\typescriptone]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-extralightitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-regular]          [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-italic]           [\s!features=\typescriptprefix{f:plex\typescriptone}]
+    \stoptypescript
+
+    % light
 
     \starttypescript [\s!sans,\s!serif,\s!mono] [plex-light] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
         \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-light]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-lightitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-regular]     [\s!features=\typescriptprefix{f:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-italic]      [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-text]        [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-textitalic]  [\s!features=\typescriptprefix{f:plex\typescriptone}]
     \stoptypescript
 
-    % [thin|light|TEXT||MEDIUM|semibold|bold|extra]
+    % regular
 
-    \starttypescript [\s!sans,\s!serif,\s!mono] [plex-text] [\s!name]
+    \starttypescript [\s!sans,\s!serif,\s!mono] [plex] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
-        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-text]         [\s!features=\typescriptprefix{f:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-textitalic]   [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-regular]      [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-italic]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-medium]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-mediumitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
     \stoptypescript
 
-    % [thin|light|text||medium|SEMIBOLD|bold|extra]
+    % text
 
-    \starttypescript [\s!sans,\s!serif,\s!mono] [plex] [\s!name]
+    \starttypescript [\s!sans,\s!serif,\s!mono] [plex-text] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
-        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-regular]        [\s!features=\typescriptprefix{f:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-italic]         [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-text]         [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-textitalic]   [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-semibold]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-semibolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
     \stoptypescript
 
-    % [thin|light|text||MEDIUM|semibold|BOLD|extra]
+    % medium
 
     \starttypescript [\s!sans,\s!serif,\s!mono] [plex-medium] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
@@ -89,9 +101,9 @@
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-bolditalic]   [\s!features=\typescriptprefix{f:plex\typescriptone}]
     \stoptypescript
 
-    % [thin|light|text||medium|SEMIBOLD|bold|EXTRA]
+    % semibold
 
-    \starttypescript [\s!sans,\s!serif,\s!mono] [plex-semibold,plex-dark,plex-black] [\s!name]
+    \starttypescript [\s!sans,\s!serif,\s!mono] [plex-semibold] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
         \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-semibold]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-semibolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
@@ -99,7 +111,19 @@
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-extraitalic]    [\s!features=\typescriptprefix{f:plex\typescriptone}]
     \stoptypescript
 
-    \starttypescript[plex,plex-thin,plex-hairline,plex-light,plex-text,plex-medium,plex-semibold,plex-dark,plex-black]
+    % bold
+
+    \starttypescript [\s!sans,\s!serif,\s!mono] [plex-bold] [\s!name]
+        \setups[\s!font:\s!fallback:\typescriptone]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-bold]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-bolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-bold]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-bolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
+    \stoptypescript
+
+    % done
+
+    \starttypescript[plex,plex-thin,plex-extralight,plex-light,plex,plex-text,plex-medium,plex-semibold,plex-bold]
         \definetypeface [\typescriptone] [\s!rm] [\s!serif] [\typescriptone] [\s!default]
         \definetypeface [\typescriptone] [\s!ss] [\s!sans]  [\typescriptone] [\s!default]
         \definetypeface [\typescriptone] [\s!tt] [\s!mono]  [\typescriptone] [\s!default]
@@ -108,38 +132,107 @@
 
     % Here's Taco's variant as used in the ConTeXt Group Journal.
 
-    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex-thin,ibmplexnarrow-thin] [\s!name]
+    \definefontfeature[plexwidened][extend=\luaexpr{1/0.85}] % An odd floating point number to correct monospace.
+
+    \definetypescriptprefix [f:scplexserif]       [\s!default,plexwidened]
+    \definetypescriptprefix [f:scplexsans]        [\s!default,plexwidened]
+    \definetypescriptprefix [f:scplexmono]        [plexwidened]
+
+    \definetypescriptprefix [f:scnarrowplexserif] [\s!default,plexwidened]
+    \definetypescriptprefix [f:scnarrowplexsans]  [\s!default,plexwidened]
+    \definetypescriptprefix [f:scnarrowplexmono]  [plexwidened]
+
+    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex-thin] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
         \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-thin]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-thinitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-text]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-textitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Widened]       [\s!file:\typescriptprefix{n:plex\typescriptone}-thin]       [\s!features=\typescriptprefix{f:scplex\typescriptone}]
+        \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps]      [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF]   [\s!rscale=0.85,method=uppercase]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Caps]          [\s!file:\typescriptprefix{n:plex\typescriptone}-thin]       [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps]
     \stoptypescript
 
-    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex-extralight,ibmplexnarrow-extralight] [\s!name]
+    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex-extralight] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
         \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-extralightitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-medium]           [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-mediumitalic]     [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Widened]       [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight]       [\s!features=\typescriptprefix{f:scplex\typescriptone}]
+        \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps]      [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF]         [\s!rscale=0.85,method=uppercase]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Caps]          [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight]       [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps]
     \stoptypescript
 
-    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex-light,ibmplexnarrow-light] [\s!name]
+    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex-light] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
         \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-light]          [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-lightitalic]    [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-semibold]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-semibolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Widened]       [\s!file:\typescriptprefix{n:plex\typescriptone}-light]          [\s!features=\typescriptprefix{f:scplex\typescriptone}]
+        \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps]      [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF]       [\s!rscale=0.85,method=uppercase]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Caps]          [\s!file:\typescriptprefix{n:plex\typescriptone}-light]          [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps]
     \stoptypescript
 
-    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex,ibmplexnarrow-light] [\s!name]
+    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex] [\s!name]
         \setups[\s!font:\s!fallback:\typescriptone]
         \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-regular]    [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:plex\typescriptone}-italic]     [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-bold]       [\s!features=\typescriptprefix{f:plex\typescriptone}]
         \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-bolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Widened]       [\s!file:\typescriptprefix{n:plex\typescriptone}-regular]    [\s!features=\typescriptprefix{f:scplex\typescriptone}]
+        \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps]      [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF]   [\s!rscale=0.85,method=uppercase]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Caps]          [\s!file:\typescriptprefix{n:plex\typescriptone}-regular]    [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps]
+    \stoptypescript
+
+    % narrow
+
+    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplexnarrow-thin] [\s!name]
+        \setups[\s!font:\s!fallback:\typescriptone]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thin]       [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thinitalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-text]       [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-textitalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}Widened]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thin]       [\s!features=\typescriptprefix{f:scnarrowplex\typescriptone}]
+        \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps]          [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF]         [\s!rscale=0.85,method=uppercase]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}Caps]          [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thin]       [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps]
+    \stoptypescript
+
+    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplexnarrow-extralight] [\s!name]
+        \setups[\s!font:\s!fallback:\typescriptone]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralight]       [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralightitalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-medium]           [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-mediumitalic]     [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}Widened]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralight]       [\s!features=\typescriptprefix{f:scnarrowplex\typescriptone}]
+        \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps]          [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF]               [\s!rscale=0.85,method=uppercase]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}Caps]          [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralight]       [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps]
+    \stoptypescript
+
+    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplexnarrow-light] [\s!name]
+        \setups[\s!font:\s!fallback:\typescriptone]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-light]          [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-lightitalic]    [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-semibold]       [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-semibolditalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}Widened]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-light]          [\s!features=\typescriptprefix{f:scnarrowplex\typescriptone}]
+        \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps]          [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF]             [\s!rscale=0.85,method=uppercase]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}Caps]          [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-light]          [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps]
     \stoptypescript
 
+    \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplexnarrow] [\s!name]
+        \setups[\s!font:\s!fallback:\typescriptone]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-regular]    [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!Italic]     [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-italic]     [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-bold]       [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-bolditalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}Widened]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-regular]    [\s!features=\typescriptprefix{f:scnarrowplex\typescriptone}]
+        \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps]          [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF]         [\s!rscale=0.85,method=uppercase]
+        \definefontsynonym     [\typescriptprefix{\typescriptone}Caps]          [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-regular]    [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps]
+    \stoptypescript
+
+
     % For now, as some day plex will have cjk, hebrew, devanagari and arabic. The abstraction is not needed but
     % this way we can add more id needed without much code.
 
@@ -152,28 +245,28 @@
     \definefontfallback [SansHebrewFallbackBold] [SansHebrewBold] [0x0590-0x05ff] [check=yes,force=no]
 
     \starttypescript [\s!sans] [ibmplex-thin] [\s!name]
-        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-thin]
                                                                             [\s!features=\typescriptprefix{f:plex\typescriptone},
                                                                              \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-medium]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-text]
                                                                             [\s!features=\typescriptprefix{f:plex\typescriptone},
                                                                              \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew]        [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-extralight]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew]        [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-thin]
                                                                             [\s!features=hebrew]
-        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-medium]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-text]
                                                                             [\s!features=hebrew]
     \stoptypescript
 
     \starttypescript [\s!sans] [ibmplex-extralight] [\s!name]
-        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-thin]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight]
                                                                             [\s!features=\typescriptprefix{f:plex\typescriptone},
                                                                              \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-text]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:plex\typescriptone}-medium]
                                                                             [\s!features=\typescriptprefix{f:plex\typescriptone},
                                                                              \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}]
-        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew]        [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-thin]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew]        [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-extralight]
                                                                             [\s!features=hebrew]
-        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-text]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-medium]
                                                                             [\s!features=hebrew]
     \stoptypescript
 
@@ -203,6 +296,60 @@
                                                                             [\s!features=hebrew]
     \stoptypescript
 
+    % narrow
+
+    \starttypescript [\s!sans] [ibmplexnarrow-thin] [\s!name]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thin]
+                                                                            [\s!features=\typescriptprefix{f:narrowplex\typescriptone},
+                                                                             \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-text]
+                                                                            [\s!features=\typescriptprefix{f:narrowplex\typescriptone},
+                                                                             \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew]        [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-thin]
+                                                                            [\s!features=hebrew]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-text]
+                                                                            [\s!features=hebrew]
+    \stoptypescript
+
+    \starttypescript [\s!sans] [ibmplexnarrow-extralight] [\s!name]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralight]
+                                                                            [\s!features=\typescriptprefix{f:narrowplex\typescriptone},
+                                                                             \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-medium]
+                                                                            [\s!features=\typescriptprefix{f:narrowplex\typescriptone},
+                                                                             \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew]        [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-extralight]
+                                                                            [\s!features=hebrew]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-medium]
+                                                                            [\s!features=hebrew]
+    \stoptypescript
+
+    \starttypescript [\s!sans] [ibmplexnarrow-light] [\s!name]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-light]
+                                                                            [\s!features=\typescriptprefix{f:narrowplex\typescriptone},
+                                                                             \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-semibold]
+                                                                            [\s!features=\typescriptprefix{f:narrowplex\typescriptone},
+                                                                             \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew]        [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-light]
+                                                                            [\s!features=hebrew]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-semibold]
+                                                                            [\s!features=hebrew]
+    \stoptypescript
+
+    \starttypescript [\s!sans] [ibmplexnarrow] [\s!name]
+        \definefontsynonym [\typescriptprefix{\typescriptone}]              [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-regular]
+                                                                            [\s!features=\typescriptprefix{f:narrowplex\typescriptone},
+                                                                             \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold]       [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-bold]
+                                                                            [\s!features=\typescriptprefix{f:narrowplex\typescriptone},
+                                                                             \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew]        [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-regular]
+                                                                            [\s!features=hebrew]
+        \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-bold]
+                                                                            [\s!features=hebrew]
+    \stoptypescript
+
     % The main definition, inspired by discussion at the 2018 ConTeXt meeting after a talk by Taco. Here
     % we default to sans serif. Taco: take your choice of math!
 
diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml
index e5db3a6f4..78dcbcde6 100644
--- a/tex/context/interface/mkii/keys-de.xml
+++ b/tex/context/interface/mkii/keys-de.xml
@@ -1247,6 +1247,7 @@
 		<cd:constant name='textstyle' value='textstil'/>
 		<cd:constant name='textwidth' value='textbreite'/>
 		<cd:constant name='threshold' value='threshold'/>
+		<cd:constant name='time' value='time'/>
 		<cd:constant name='title' value='titel'/>
 		<cd:constant name='titlecolor' value='titelfarbe'/>
 		<cd:constant name='titlecommand' value='titlecommand'/>
diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml
index e948cda23..a0a302d34 100644
--- a/tex/context/interface/mkii/keys-en.xml
+++ b/tex/context/interface/mkii/keys-en.xml
@@ -1247,6 +1247,7 @@
 		<cd:constant name='textstyle' value='textstyle'/>
 		<cd:constant name='textwidth' value='textwidth'/>
 		<cd:constant name='threshold' value='threshold'/>
+		<cd:constant name='time' value='time'/>
 		<cd:constant name='title' value='title'/>
 		<cd:constant name='titlecolor' value='titlecolor'/>
 		<cd:constant name='titlecommand' value='titlecommand'/>
diff --git a/tex/context/interface/mkiv/context-en.xml b/tex/context/interface/mkiv/context-en.xml
index 508e2fc7c..d0e93c410 100644
--- a/tex/context/interface/mkiv/context-en.xml
+++ b/tex/context/interface/mkiv/context-en.xml
@@ -10233,10 +10233,10 @@
       <cd:constant type="cd:dimension"/>
      </cd:parameter>
      <cd:parameter name="ntop">
-      <cd:constant type="cd:dimension"/>
+      <cd:constant type="cd:number"/>
      </cd:parameter>
      <cd:parameter name="nbottom">
-      <cd:constant type="cd:dimension"/>
+      <cd:constant type="cd:number"/>
      </cd:parameter>
      <cd:parameter name="step">
       <cd:constant type="small"/>
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index f373195d9..d8dc51e14 100644
Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ
diff --git a/tex/context/interface/mkiv/i-floats.xml b/tex/context/interface/mkiv/i-floats.xml
index 2b25adf49..4b26b9e95 100644
--- a/tex/context/interface/mkiv/i-floats.xml
+++ b/tex/context/interface/mkiv/i-floats.xml
@@ -186,10 +186,10 @@
                     <cd:constant type="cd:dimension"/>
                 </cd:parameter>
                 <cd:parameter name="ntop">
-                    <cd:constant type="cd:dimension"/>
+                    <cd:constant type="cd:number"/>
                 </cd:parameter>
                 <cd:parameter name="nbottom">
-                    <cd:constant type="cd:dimension"/>
+                    <cd:constant type="cd:number"/>
                 </cd:parameter>
                 <cd:parameter name="step">
                     <cd:constant type="small"/>
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 3dcf09ed4..fac1c6288 100644
Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ
diff --git a/tex/context/modules/mkiv/m-matrix.mkiv b/tex/context/modules/mkiv/m-matrix.mkiv
index 9cac69672..4a0bd712d 100644
--- a/tex/context/modules/mkiv/m-matrix.mkiv
+++ b/tex/context/modules/mkiv/m-matrix.mkiv
@@ -23,6 +23,8 @@
 
 \startluacode
 
+local tonumber, type = tonumber, type
+
 local settings_to_hash = utilities.parsers.settings_to_hash
 local formatters       = string.formatters
 local copy             = table.copy
@@ -114,7 +116,7 @@ function matrix.typeset(m,options)
             if type(m[1]) ~= "table" then
                 m = { copy(m) }
             end
-            for i=1, #m do
+            for i=1,#m do
                 local mi = m[i]
                 for j=1,#mi do
                     context.NC()
@@ -164,9 +166,11 @@ function matrix.swapcolumns(t, i, j)
     return t
 end
 
-matrix.swapC = matrix.swapcolumns
-matrix.swapR = matrix.swaprows
-matrix.swap  = matrix.swaprows
+matrix.swapC       = matrix.swapcolumns
+matrix.swapR       = matrix.swaprows
+matrix.swapcolumns = matrix.swapcolumns
+matrix.swaprows    = matrix.swaprows
+matrix.swap        = matrix.swaprows
 
 -- replace i-th row with factor * (i-th row)
 
@@ -299,7 +303,7 @@ local function determinant(m)
         end
         return s*d
     else
-        return "error: not a square matrix" -- not context(..)
+        return "error: not a square matrix"
     end
 end
 
@@ -371,7 +375,7 @@ matrix.rowEchelon = rowechelon
 
 -- make matrices until its determinant is not 0
 
-function matrix.make(m,n,low,high) -- m and n swapped
+local function make(m,n,low,high) -- m and n swapped
     if not n then
         n = 10
     end
@@ -401,6 +405,9 @@ function matrix.make(m,n,low,high) -- m and n swapped
     end
 end
 
+matrix.make  = make
+matrix.makeR = matrix.make
+
 -- extract submatrix by using
 
 local function submatrix(t,i,j)
@@ -420,10 +427,11 @@ local function submatrix(t,i,j)
 end
 
 matrix.submatrix = submatrix
+matrix.subMatrix = submatrix
 
 -- calculating determinant using Laplace Expansion
 
-function matrix.laplace(t) -- not sure if this is the most effient but
+local function laplace(t) -- not sure if this is the most effient but
     local factors = { 1 }  -- it's not used for number crunching anyway
     local data    = copy(t)
     local det     = 0
@@ -461,6 +469,8 @@ function matrix.laplace(t) -- not sure if this is the most effient but
     return det
 end
 
+matrix.laplace = laplace
+
 --  solve the linear equation m X = c
 
 local function solve(m,c)
@@ -518,6 +528,74 @@ end
 
 matrix.inverse = inverse
 
+-- create zero and identity matrix
+
+local function makeM(k,v)
+    local tt = { }
+    for i=1,k do
+        local temp = { }
+        for j=1,k do
+            temp[j] = 0
+        end
+        tt[i] = temp
+    end
+    if v and v > 0 then
+        for i=1,k do
+            tt[i][i] = 1
+        end
+    end
+    return tt
+end
+
+matrix.makeM        = makeM
+matrix.makeidentity = makeM
+matrix.makezero     = makeM
+
+-- append the rows of the second matrix  to the bottom of the first matrix
+
+local function joinrows(t1, t2)
+    local nt1 = #t1
+    local nt2 = #t2
+    if (nt1*nt2 > 0) and (#t1[1] ~= #t2[1]) then
+        return "error: different number of columns"
+    else
+        for i=1,nt2 do
+            t1[nt1+i] = t2[i]
+        end
+        return t1
+    end
+end
+
+matrix.joinrows = joinrows
+matrix.joinRows = joinrows
+
+-- append the columns of the second matrix  to the right of the first matrix
+
+local function joincolumns(t1, t2)
+    local nt1 = #t1
+    local nt2 = #t2
+    if nt1 == 0 then
+        return t2
+    end
+    if nt2 == 0 then
+        return t1
+    end
+    if nt1 ~= nt2 then
+        return "error: different number of rows"
+    end
+    nt3 = #t2[1]
+    for i=1,nt1 do
+        local temp = t2[i]
+        for j= 1, nt3 do
+            insert(t1[i],temp[j])
+        end
+    end
+    return t1
+end
+
+matrix.joincolumns = joincolumns
+matrix.joinColumns = joincolumns
+
 \stopluacode
 
 \stopmodule
@@ -570,6 +648,7 @@ document.DemoMatrixC = {
 
 \startbuffer
 \ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n"))}
+$\qquad\qquad$
 \ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n", 4, 8))}
 \stopbuffer
 
@@ -581,9 +660,10 @@ document.DemoMatrixC = {
 
 \startbuffer
 \startluacode
-    moduledata.matrix.typeset(moduledata.matrix.make(4,3, 0,5))
+    moduledata.matrix.typeset(moduledata.matrix.makeR(4,3, 0,5))
     context.qquad()
-    moduledata.matrix.typeset(moduledata.matrix.make(5,5,-1,5))
+    context("\\qquad")
+    moduledata.matrix.typeset(moduledata.matrix.makeR(5,5,-1,5))
 \stopluacode
 \stopbuffer
 
@@ -591,7 +671,7 @@ document.DemoMatrixC = {
 
 \stopsubject
 
-\startsubject[title={Swap two rows (2 and 4)}]
+\startsubject[title={Swap two rows (ex: 2 and 4)}]
 
 \startbuffer
 \startluacode
@@ -605,13 +685,13 @@ document.DemoMatrixC = {
 
 \stopsubject
 
-\startsubject[title={Swap two columns (2 and 4)}]
+\startsubject[title={Swap two columns (ex: 1 and 3)}]
 
 \startbuffer
 \startluacode
     moduledata.matrix.typeset(document.DemoMatrixA)
     context("$\\qquad \\Rightarrow \\qquad$")
-    moduledata.matrix.typeset(moduledata.matrix.swapcolumns(document.DemoMatrixA,2, 4))
+    moduledata.matrix.typeset(moduledata.matrix.swapcolumns(document.DemoMatrixA,1, 3))
 \stopluacode
 \stopbuffer
 
@@ -726,7 +806,7 @@ context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 }))
     }
     moduledata.matrix.typeset(m, {fences="bars"})
     context("$\\qquad = \\qquad$")
-    moduledata.matrix.determinant(m)
+    context(moduledata.matrix.determinant(m))
 \stopluacode
 \stopbuffer
 
@@ -864,4 +944,51 @@ context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 }))
 
 \stopsubject
 
+\startsubject[title={make matrices(zero, identiry, random}]
+
+\startbuffer
+\startluacode
+    moduledata.matrix.typeset(moduledata.matrix.makeM(3, 0))
+    context.qquad()
+    moduledata.matrix.typeset(moduledata.matrix.makeM(3, 1))
+    context.qquad()
+    moduledata.matrix.typeset(moduledata.matrix.makeR(4,3))
+\stopluacode
+\stopbuffer
+
+\getbuffer[demo]
+
+\stopsubject
+
+\startsubject[title={join rows, join columns}]
+
+\startbuffer
+\startluacode
+    local mat1 = moduledata.matrix.makeR(3, 4)
+    local mat2 = moduledata.matrix.makeR(4, 3)
+
+    context("Appending as columns: ")
+    context.blank()
+    moduledata.matrix.typeset(mat1)
+    context("$\\&$")
+    moduledata.matrix.typeset(mat1)
+    context("\\quad $\\Rightarrow$ \\quad")
+    moduledata.matrix.joinColumns(mat1, mat1)
+    moduledata.matrix.typeset(mat1)
+    context.blank()
+    context("Appending as rows: ")
+    context.blank()
+    moduledata.matrix.typeset(mat2)
+    context("$\\&$")
+    moduledata.matrix.typeset(mat2)
+    context("\\quad $\\Rightarrow$ \\quad")
+    moduledata.matrix.joinRows(mat2, mat2)
+    moduledata.matrix.typeset(mat2)
+\stopluacode
+\stopbuffer
+
+\getbuffer[demo]
+
+\stopsubject
+
 \stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-system.lua b/tex/context/modules/mkiv/s-fonts-system.lua
index b91b3e75d..e05eef0fa 100644
--- a/tex/context/modules/mkiv/s-fonts-system.lua
+++ b/tex/context/modules/mkiv/s-fonts-system.lua
@@ -30,11 +30,15 @@ if not modules then modules = { } end modules ['s-fonts-system'] = {
 moduledata.fonts        = moduledata.fonts        or { }
 moduledata.fonts.system = moduledata.fonts.system or { }
 
-local lower = string.lower
-
 local context = context
 local NC, NR, HL = context.NC, context.NR, context.HL
-local bold = context.bold
+local ctx_bold = context.bold
+local ctx_verbatim = context.verbatim
+local lpegmatch = lpeg.match
+local sortedhash = table.sortedhash
+local formatters = string.formatters
+local concat = table.concat
+local lower = string.lower
 
 local function allfiles(specification)
     local pattern = lower(specification.pattern or "")
@@ -54,12 +58,12 @@ function moduledata.fonts.system.showinstalled(specification)
     if files then
         context.starttabulate { "|Tl|Tl|Tl|Tl|Tl|Tl|" }
             HL()
-            NC() bold("filename")
-            NC() bold("fontname")
-            NC() bold("subfamily")
-            NC() bold("variant")
-            NC() bold("weight")
-            NC() bold("width")
+            NC() ctx_bold("filename")
+            NC() ctx_bold("fontname")
+            NC() ctx_bold("subfamily")
+            NC() ctx_bold("variant")
+            NC() ctx_bold("weight")
+            NC() ctx_bold("width")
             NC() NR()
             HL()
             for filename, data in table.sortedpairs(files) do
@@ -80,25 +84,121 @@ function moduledata.fonts.system.cacheinstalled(specification)
     local files = allfiles(specification)
     if files then
         local threshold = tonumber(specification.threshold)
+        local suffixes  = specification.suffixes
+        if suffixes then
+            suffixes = utilities.parsers.settings_to_set(suffixes)
+        else
+            suffixes = { otf = true, ttf = true }
+        end
         for filename, data in table.sortedpairs(files) do
             if string.find(filename," ") then
                 -- skip this one
-            else
-                local s = file.suffix(filename)
-                if s == "otf" or s == "ttf" then
-                    local fullname = resolvers.findfile(filename)
-                    context.start()
-                    context.type(fullname)
-                    context.par()
-                    if threshold and file.size(fullname) > threshold then
-                        logs.report("fonts","ignoring : %s",fullname)
-                    else
-                        logs.report("fonts","caching  : %s",fullname)
-                        context.definedfont { filename }
+            elseif suffixes[file.suffix(filename)] then
+                local fullname = resolvers.findfile(filename)
+                context.start()
+                context.type(fullname)
+                context.par()
+                if threshold and file.size(fullname) > threshold then
+                    logs.report("fonts","ignoring : %s",fullname)
+                else
+                    logs.report("fonts","caching  : %s",fullname)
+                    context.definedfont { filename }
+                end
+                context.stop()
+            end
+        end
+    end
+end
+
+local splitter = lpeg.splitat(lpeg.S("._"),true)
+
+local method = 3
+
+function moduledata.fonts.system.showinstalledglyphnames(specification)
+    specification = interfaces.checkedspecification(specification)
+    local paths   = caches.getreadablepaths()
+    local files   = { }
+    local names   = table.setmetatableindex("table")
+    local f_u     = formatters["%04X"]
+    for i=1,#paths do
+        local list = dir.glob(paths[i].."/fonts/o*/**.tmc")
+        for i=1,#list do
+            files[list[i]] = true
+        end
+    end
+    for filename in table.sortedhash(files) do
+        logs.report("system","fontfile: %s",file.nameonly(filename))
+        local data = table.load(filename)
+        if data then
+            if method == 1 then
+                local unicodes = data.resources.unicodes
+                if unicodes then
+                    for n, u in sortedhash(unicodes) do
+                        if u >= 0xF0000 or (u >= 0xE000 and u <= 0xF8FF) then
+                            -- skip
+                        else
+                             local f = lpegmatch(splitter,n) or n
+                             if #f > 0 then
+                                 local t = names[f]
+                                 t[u] = (t[u] or 0) + 1
+                             end
+                        end
+                    end
+                end
+            elseif method == 2 then
+                local unicodes = data.resources.unicodes
+                if unicodes then
+                    for n, u in sortedhash(unicodes) do
+                        if u >= 0xF0000 or (u >= 0xE000 and u <= 0xF8FF) then
+                            -- skip
+                        else
+                            local t = names[n]
+                            t[u] = (t[u] or 0) + 1
+                        end
                     end
-                    context.stop()
                 end
+            elseif method == 3 then
+                local descriptions = data.descriptions
+                if descriptions then
+                    for u, d in sortedhash(descriptions) do
+                        local n = d.name
+                        local u = d.unicode
+                        if n and u then
+                            if type(u) == "table" then
+                                local t = { }
+                                for i=1,#u do
+                                    t[i] = f_u(u[i])
+                                end
+                                u = concat(t," ")
+                            end
+                            local t = names[n]
+                            t[u] = (t[u] or 0) + 1
+                        end
+                    end
+                end
+            else
+                -- nothing
             end
         end
     end
+    if next(names) then
+        context.starttabulate { "|l|pl|" }
+        local f_u = formatters["%04X~(%i)"]
+        local f_s = formatters["%s~(%i)"]
+        for k, v in sortedhash(names) do
+            local t = { }
+            for k, v in sortedhash(v) do
+                if type(k) == "string" then
+                    t[#t+1] = f_s(k,v)
+                else
+                    t[#t+1] = f_u(k,v)
+                end
+            end
+            NC() ctx_verbatim(k)
+            NC() context("% t",t)
+            NC() NR()
+        end
+        context.stoptabulate()
+    end
+    table.save("s-fonts-system-glyph-names.lua",names)
 end
diff --git a/tex/context/modules/mkiv/s-fonts-system.mkiv b/tex/context/modules/mkiv/s-fonts-system.mkiv
index a9d33d27e..5613701d9 100644
--- a/tex/context/modules/mkiv/s-fonts-system.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-system.mkiv
@@ -24,8 +24,9 @@
 
 \registerctxluafile{s-fonts-system}{}
 
-\installmodulecommandluasingle \showinstalledfonts  {moduledata.fonts.system.showinstalled}
-\installmodulecommandluasingle \cacheinstalledfonts {moduledata.fonts.system.cacheinstalled}
+\installmodulecommandluasingle \showinstalledfonts      {moduledata.fonts.system.showinstalled}
+\installmodulecommandluasingle \cacheinstalledfonts     {moduledata.fonts.system.cacheinstalled}
+\installmodulecommandluasingle \showinstalledglyphnames {moduledata.fonts.system.showinstalledglyphnames}
 
 \stopmodule
 
@@ -36,6 +37,12 @@
 \starttext
 
 %     \showinstalledfonts
-    \cacheinstalledfonts[threshold=4000000]
+
+%     \enabletrackers[otf.keepnames]
+
+%     \cacheinstalledfonts[threshold=4000000,suffixes={otf,ttf,afm,pfb}]
+%     \cacheinstalledfonts[threshold=2000000,suffixes={otf,ttf,afm,pfb}]
+
+    \showinstalledglyphnames
 
 \stoptext
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index adc2c6202..90f8f4f00 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  : 10/03/18 16:02:19
+-- merge date  : 10/08/18 17:44:41
 
 do -- begin closure to overcome local limits and interference
 
@@ -14218,7 +14218,7 @@ if not modules then modules={} end modules ['font-cff']={
 }
 local next,type,tonumber=next,type,tonumber
 local byte,char,gmatch=string.byte,string.char,string.gmatch
-local concat,remove=table.concat,table.remove
+local concat,remove,unpack=table.concat,table.remove,table.unpack
 local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max
 local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct
 local lpegmatch=lpeg.match
@@ -20851,7 +20851,7 @@ local function checklookups(fontdata,missing,nofmissing)
       end
     end
     if next(done) then
-      report_unicode("not unicoded: % t",sortedkeys(done))
+      report_unicodes("not unicoded: % t",sortedkeys(done))
     end
   end
 end
@@ -21040,9 +21040,25 @@ local function unifyglyphs(fontdata,usenames)
   fontdata.hashmethod=hashmethod
   return indices,names
 end
-local p_bogusname=(
-  (P("uni")+P("UNI")+P("Uni")+P("U")+P("u"))*S("Xx")^0*R("09","AF")^1+(P("identity")+P("Identity")+P("IDENTITY"))*R("09","AF")^1+(P("index")+P("Index")+P("INDEX"))*R("09")^1
-)*(P(-1)+P("."))
+local p_crappyname do
+  local p_hex=R("af","AF","09")
+  local p_digit=R("09")
+  local p_done=S("._-")^0+P(-1)
+  local p_alpha=R("az","AZ")
+  local p_ALPHA=R("AZ")
+  p_crappyname=(
+    lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
++lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1
++lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1
++p_digit*p_hex^3+p_alpha*p_digit^1
++P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1
+  )*p_done
+end
+local forcekeep=false 
+directives.register("otf.keepnames",function(v)
+  report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+  forcekeep=v
+end)
 local function stripredundant(fontdata)
   local descriptions=fontdata.descriptions
   if descriptions then
@@ -21058,7 +21074,7 @@ local function stripredundant(fontdata)
     else
       for unicode,d in next,descriptions do
         local name=d.name
-        if name and lpegmatch(p_bogusname,name) then
+        if name and lpegmatch(p_crappyname,name) then
           d.name=nil
           n=n+1
         end
@@ -21078,6 +21094,7 @@ local function stripredundant(fontdata)
     end
   end
 end
+readers.stripredundant=stripredundant
 function readers.getcomponents(fontdata) 
   local resources=fontdata.resources
   if resources then
@@ -32882,6 +32899,7 @@ function afm.load(filename)
       if data then
         afmenhancers.apply(data,filename)
         fonts.mappings.addtounicode(data,filename)
+        otfreaders.stripredundant(data)
         otfreaders.pack(data)
         data.size=size
         data.time=time
-- 
cgit v1.2.3