texlive[54364] trunk: context (16mar20)

commits+karl at tug.org commits+karl at tug.org
Mon Mar 16 22:11:41 CET 2020


Revision: 54364
          http://tug.org/svn/texlive?view=revision&revision=54364
Author:   karl
Date:     2020-03-16 22:11:40 +0100 (Mon, 16 Mar 2020)
Log Message:
-----------
context (16mar20)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun
    trunk/Master/bin/win32/mtxrun.lua
    trunk/Master/texmf-dist/context/data/vscode/settings.json
    trunk/Master/texmf-dist/context/data/vscode/vscode-context.cmd
    trunk/Master/texmf-dist/doc/context/documents/general/manuals/luametatex.pdf
    trunk/Master/texmf-dist/doc/context/documents/general/manuals/tools-mkiv.pdf
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-libraries.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-pdf.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/tools/tools-mkiv.tex
    trunk/Master/texmf-dist/doc/man/man1/context.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/luatools.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-babel.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-base.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-bibtex.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-cache.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-chars.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-check.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-colors.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-context.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-dvi.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-epub.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-evohome.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-fcd.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-flac.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-fonts.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-grep.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-interface.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-metapost.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-modules.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-package.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-patterns.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-pdf.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-plain.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-profile.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-rsync.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-scite.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-server.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-texworks.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-timing.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-tools.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-unicode.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-unzip.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-update.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-vscode.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-watch.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtx-youless.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/texexec.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/texmfstart.man1.pdf
    trunk/Master/texmf-dist/metapost/context/base/mpii/mp-tool.mpii
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-lmtx.mpxl
    trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tool.mpiv
    trunk/Master/texmf-dist/scripts/context/lua/mtxrun.lua
    trunk/Master/texmf-dist/scripts/context/stubs/mswin/mtxrun.lua
    trunk/Master/texmf-dist/scripts/context/stubs/unix/mtxrun
    trunk/Master/texmf-dist/scripts/context/stubs/win64/mtxrun.lua
    trunk/Master/texmf-dist/tex/context/base/mkii/cont-new.mkii
    trunk/Master/texmf-dist/tex/context/base/mkii/context.mkii
    trunk/Master/texmf-dist/tex/context/base/mkii/syst-new.mkii
    trunk/Master/texmf-dist/tex/context/base/mkiv/attr-col.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/attr-ini.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/back-exp.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/char-utf.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/cldf-bas.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/colo-ini.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/cont-new.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkiv/data-ini.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/data-tex.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/driv-shp.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-ctx.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-hsh.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-lib.mkvi
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-map.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-ocl.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-ogr.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-osd.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-ota.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-ots.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-oup.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-pre.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/l-macro-imp-optimize.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/l-os.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/lang-ini.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/lang-url.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/lpdf-lmt.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/luat-cod.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/luat-fmt.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/m-fonts-plugins.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/math-ini.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/math-tag.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/meta-ini.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/mlib-lmp.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/mlib-svg.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/node-aux.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/node-ini.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/node-nut.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/node-res.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/sort-ini.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/spac-prf.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/status-files.pdf
    trunk/Master/texmf-dist/tex/context/base/mkiv/status-lua.pdf
    trunk/Master/texmf-dist/tex/context/base/mkiv/symb-ini.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/syst-ini.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkiv/tabl-tbl.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/trac-inf.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/typo-brk.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/typo-cap.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/typo-dha.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/typo-itc.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/typo-rep.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-copas.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-str.lua
    trunk/Master/texmf-dist/tex/context/modules/mkiv/s-math-ligatures.mkiv
    trunk/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.lua
    trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-basics-nod.lua
    trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-core.lua
    trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-fonts-merged.lua

Added Paths:
-----------
    trunk/Master/texmf-dist/context/data/vscode/tasks.json
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-imp-tweaks.lua

Modified: trunk/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun	2020-03-16 21:11:40 UTC (rev 54364)
@@ -3806,7 +3806,7 @@
 
 package.loaded["l-os"] = package.loaded["l-os"] or true
 
--- original size: 19102, stripped down to: 10192
+-- original size: 19120, stripped down to: 10208
 
 if not modules then modules={} end modules ['l-os']={
  version=1.001,
@@ -4101,7 +4101,7 @@
 end
 local d
 function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ d=d or ((tonumber(date("%H")) or 0)-(tonumber(date("!%H")) or 0))
  if delta then
   if d>0 then
    return format("+%02i:00",d)
@@ -6563,7 +6563,7 @@
 
 package.loaded["util-str"] = package.loaded["util-str"] or true
 
--- original size: 45188, stripped down to: 22734
+-- original size: 45153, stripped down to: 22734
 
 if not modules then modules={} end modules ['util-str']={
  version=1.001,
@@ -10079,7 +10079,7 @@
 
 package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
 
--- original size: 25959, stripped down to: 14893
+-- original size: 26186, stripped down to: 14893
 
 
 local socket=socket or require("socket")
@@ -13961,7 +13961,7 @@
 
 package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
 
--- original size: 9973, stripped down to: 7492
+-- original size: 10184, stripped down to: 7500
 
 if not modules then modules={} end modules ['trac-inf']={
  version=1.001,
@@ -13995,10 +13995,11 @@
 end
 local ticks=clock
 local seconds=function(n) return n or 0 end
-if lua.getpreciseticks then
+if os.type~="windows" then
+elseif lua.getpreciseticks then
  ticks=lua.getpreciseticks
  seconds=lua.getpreciseseconds
-elseif FFISUPPORTED and ffi and os.type=="windows" then
+elseif FFISUPPORTED then
  local okay,kernel=pcall(ffi.load,"kernel32")
  if kernel then
   local tonumber=ffi.number or tonumber
@@ -14136,12 +14137,12 @@
   end)
   if LUATEXENGINE=="luametatex" then
    register("used engine",function()
-    return format("%s version %s, functionality level %s, format id %s",
-     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID)
+    return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID,status.used_compiler)
    end)
   else
    register("used engine",function()
-    return format("%s version %s with functionality level %s, banner: %s",
+    return format("%s version: %s, functionality level: %s, banner: %s",
      LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
    end)
   end
@@ -14149,7 +14150,7 @@
    return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
   end)
   register("callbacks",statistics.callbacks)
-  if TEXENGINE=="luajittex" and JITSUPPORTED then
+  if JITSUPPORTED then
    local jitstatus=jit.status
    if jitstatus then
     local jitstatus={ jitstatus() }
@@ -14183,7 +14184,7 @@
 end
 function statistics.memused() 
  local round=math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB)",
+ return format("%s MB, ctx: %s MB, max: %s MB",
   round(collectgarbage("count")/1000),
   round(status.luastate_bytes/1000000),
   status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
@@ -20789,7 +20790,7 @@
 
 package.loaded["data-ini"] = package.loaded["data-ini"] or true
 
--- original size: 11019, stripped down to: 7086
+-- original size: 10847, stripped down to: 7086
 
 if not modules then modules={} end modules ['data-ini']={
  version=1.001,
@@ -25784,7 +25785,7 @@
 
 package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
 
--- original size: 13964, stripped down to: 10026
+-- original size: 13843, stripped down to: 9991
 
 if not modules then modules={} end modules ['luat-fmt']={
  version=1.001,
@@ -25821,9 +25822,6 @@
  if arguments.errors then
   flags[#flags+1]="--c:errors"
  end
- if arguments.jit then
-  flags[#flags+1]="--c:jiton"
- end
  if arguments.ansi then
   flags[#flags+1]="--c:ansi"
  end
@@ -25991,9 +25989,9 @@
  if silent then
   specification.redirect="> temp.log"
  end
- statistics.starttiming()
+ statistics.starttiming("format")
  local result=runner(specification)
- local runtime=statistics.stoptiming()
+ statistics.stoptiming("format")
  if silent then
   os.remove("temp.log")
  end
@@ -26011,7 +26009,7 @@
  report_format("secondary flags  : %s",secondaryflags)
   end
  report_format("context file     : %s",fulltexsourcename)
- report_format("run time         : %.3f seconds",runtime)
+ report_format("run time         : %.3f seconds",statistics.elapsed("format"))
  report_format("return value     : %s",result==0 and "okay" or "error")
  report_format()
  lfs.chdir(startupdir)
@@ -26117,8 +26115,8 @@
 
 -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
 -- skipped libraries : -
--- original bytes    : 1038245
--- stripped bytes    : 409841
+-- original bytes    : 1038373
+-- stripped bytes    : 409980
 
 -- end library merge
 

Modified: trunk/Master/bin/win32/mtxrun.lua
===================================================================
--- trunk/Master/bin/win32/mtxrun.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/bin/win32/mtxrun.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -3806,7 +3806,7 @@
 
 package.loaded["l-os"] = package.loaded["l-os"] or true
 
--- original size: 19102, stripped down to: 10192
+-- original size: 19120, stripped down to: 10208
 
 if not modules then modules={} end modules ['l-os']={
  version=1.001,
@@ -4101,7 +4101,7 @@
 end
 local d
 function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ d=d or ((tonumber(date("%H")) or 0)-(tonumber(date("!%H")) or 0))
  if delta then
   if d>0 then
    return format("+%02i:00",d)
@@ -6563,7 +6563,7 @@
 
 package.loaded["util-str"] = package.loaded["util-str"] or true
 
--- original size: 45188, stripped down to: 22734
+-- original size: 45153, stripped down to: 22734
 
 if not modules then modules={} end modules ['util-str']={
  version=1.001,
@@ -10079,7 +10079,7 @@
 
 package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
 
--- original size: 25959, stripped down to: 14893
+-- original size: 26186, stripped down to: 14893
 
 
 local socket=socket or require("socket")
@@ -13961,7 +13961,7 @@
 
 package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
 
--- original size: 9973, stripped down to: 7492
+-- original size: 10184, stripped down to: 7500
 
 if not modules then modules={} end modules ['trac-inf']={
  version=1.001,
@@ -13995,10 +13995,11 @@
 end
 local ticks=clock
 local seconds=function(n) return n or 0 end
-if lua.getpreciseticks then
+if os.type~="windows" then
+elseif lua.getpreciseticks then
  ticks=lua.getpreciseticks
  seconds=lua.getpreciseseconds
-elseif FFISUPPORTED and ffi and os.type=="windows" then
+elseif FFISUPPORTED then
  local okay,kernel=pcall(ffi.load,"kernel32")
  if kernel then
   local tonumber=ffi.number or tonumber
@@ -14136,12 +14137,12 @@
   end)
   if LUATEXENGINE=="luametatex" then
    register("used engine",function()
-    return format("%s version %s, functionality level %s, format id %s",
-     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID)
+    return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID,status.used_compiler)
    end)
   else
    register("used engine",function()
-    return format("%s version %s with functionality level %s, banner: %s",
+    return format("%s version: %s, functionality level: %s, banner: %s",
      LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
    end)
   end
@@ -14149,7 +14150,7 @@
    return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
   end)
   register("callbacks",statistics.callbacks)
-  if TEXENGINE=="luajittex" and JITSUPPORTED then
+  if JITSUPPORTED then
    local jitstatus=jit.status
    if jitstatus then
     local jitstatus={ jitstatus() }
@@ -14183,7 +14184,7 @@
 end
 function statistics.memused() 
  local round=math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB)",
+ return format("%s MB, ctx: %s MB, max: %s MB",
   round(collectgarbage("count")/1000),
   round(status.luastate_bytes/1000000),
   status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
@@ -20789,7 +20790,7 @@
 
 package.loaded["data-ini"] = package.loaded["data-ini"] or true
 
--- original size: 11019, stripped down to: 7086
+-- original size: 10847, stripped down to: 7086
 
 if not modules then modules={} end modules ['data-ini']={
  version=1.001,
@@ -25784,7 +25785,7 @@
 
 package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
 
--- original size: 13964, stripped down to: 10026
+-- original size: 13843, stripped down to: 9991
 
 if not modules then modules={} end modules ['luat-fmt']={
  version=1.001,
@@ -25821,9 +25822,6 @@
  if arguments.errors then
   flags[#flags+1]="--c:errors"
  end
- if arguments.jit then
-  flags[#flags+1]="--c:jiton"
- end
  if arguments.ansi then
   flags[#flags+1]="--c:ansi"
  end
@@ -25991,9 +25989,9 @@
  if silent then
   specification.redirect="> temp.log"
  end
- statistics.starttiming()
+ statistics.starttiming("format")
  local result=runner(specification)
- local runtime=statistics.stoptiming()
+ statistics.stoptiming("format")
  if silent then
   os.remove("temp.log")
  end
@@ -26011,7 +26009,7 @@
  report_format("secondary flags  : %s",secondaryflags)
   end
  report_format("context file     : %s",fulltexsourcename)
- report_format("run time         : %.3f seconds",runtime)
+ report_format("run time         : %.3f seconds",statistics.elapsed("format"))
  report_format("return value     : %s",result==0 and "okay" or "error")
  report_format()
  lfs.chdir(startupdir)
@@ -26117,8 +26115,8 @@
 
 -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
 -- skipped libraries : -
--- original bytes    : 1038245
--- stripped bytes    : 409841
+-- original bytes    : 1038373
+-- stripped bytes    : 409980
 
 -- end library merge
 

Modified: trunk/Master/texmf-dist/context/data/vscode/settings.json
===================================================================
--- trunk/Master/texmf-dist/context/data/vscode/settings.json	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/context/data/vscode/settings.json	2020-03-16 21:11:40 UTC (rev 54364)
@@ -23,7 +23,7 @@
     "workbench.colorTheme": "ConTeXt",
  // "[context.pdf]": { "files.encoding": "cp1252"},
     "terminal.integrated.fontSize": 10,
-    "terminal.integrated.rendererType": "dom",
+    "terminal.integrated.rendererType": "canvas",
     "workbench.colorCustomizations": {
         "terminal.ansiBlack":         "#000000",
         "terminal.ansiWhite":         "#FFFFFF",

Added: trunk/Master/texmf-dist/context/data/vscode/tasks.json
===================================================================
--- trunk/Master/texmf-dist/context/data/vscode/tasks.json	                        (rev 0)
+++ trunk/Master/texmf-dist/context/data/vscode/tasks.json	2020-03-16 21:11:40 UTC (rev 54364)
@@ -0,0 +1,73 @@
+{
+ "name" : "context",
+ "tasks" : [
+  {
+   "command" : "context     --autogenerate --autopdf ${file}",
+   "group" : "build",
+   "label" : "process tex file",
+   "presentation" : {
+    "clear" : true,
+    "echo" : true,
+    "focus" : false,
+    "panel" : "shared",
+    "reveal" : "always",
+    "showReuseMessage" : false
+   },
+   "type" : "shell",
+   "windows" : {
+    "command" : "chcp 65001 ; context.exe --autogenerate --autopdf ${file}"
+   }
+  },
+  {
+   "command" : "mtxrun     --autogenerate --script check ${file}",
+   "group" : "build",
+   "label" : "check tex file",
+   "presentation" : {
+    "clear" : true,
+    "echo" : true,
+    "focus" : false,
+    "panel" : "shared",
+    "reveal" : "always",
+    "showReuseMessage" : false
+   },
+   "type" : "shell",
+   "windows" : {
+    "command" : "chcp 65001 ; mtxrun.exe --autogenerate --script check ${file}"
+   }
+  },
+  {
+   "command" : "mtxrun     --script fonts --reload --force",
+   "group" : "build",
+   "label" : "identify fonts",
+   "presentation" : {
+    "clear" : true,
+    "echo" : true,
+    "focus" : false,
+    "panel" : "shared",
+    "reveal" : "always",
+    "showReuseMessage" : false
+   },
+   "type" : "shell",
+   "windows" : {
+    "command" : "chcp 65001 ; mtxrun.exe --script fonts --reload --force"
+   }
+  },
+  {
+   "command" : "mtxrun     --script ${file}",
+   "group" : "build",
+   "label" : "process lua file",
+   "presentation" : {
+    "clear" : true,
+    "echo" : true,
+    "focus" : false,
+    "panel" : "shared",
+    "reveal" : "always",
+    "showReuseMessage" : false
+   },
+   "type" : "shell",
+   "windows" : {
+    "command" : "chcp 65001 ; mtxrun.exe --script ${file}"
+   }
+  }
+ ]
+}
\ No newline at end of file

Modified: trunk/Master/texmf-dist/context/data/vscode/vscode-context.cmd
===================================================================
--- trunk/Master/texmf-dist/context/data/vscode/vscode-context.cmd	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/context/data/vscode/vscode-context.cmd	2020-03-16 21:11:40 UTC (rev 54364)
@@ -4,4 +4,4 @@
 
 rem I need to figure out how to detach the instance
 
-start "vs code context" code --ignore-gpu-blacklist --reuse-window --extensions-dir  %~dp0\extensions --install-extension context %* 2>&1 nul
+start "vs code context" code --reuse-window --extensions-dir  %~dp0\extensions --install-extension context %* 2>&1 nul

Modified: trunk/Master/texmf-dist/doc/context/documents/general/manuals/luametatex.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/context/documents/general/manuals/tools-mkiv.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-callbacks.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -16,7 +16,7 @@
 \libindex{known}
 
 This library has functions that register, find and list callbacks. Callbacks are
-\LUA\ functions that are called in well defined places. There are two kind of
+\LUA\ functions that are called in well defined places. There are two kinds of
 callbacks: those that mix with existing functionality, and those that (when
 enabled) replace functionality. In mosty cases the second category is expected to
 behave similar to the built in functionality because in a next step specific
@@ -408,7 +408,7 @@
 internal linebreak algorithm on the list that starts at \type {<head>}.
 Otherwise, the \type {<node>} you return is supposed to be the head of a list of
 nodes that are all allowed in vertical mode, and at least one of those has to
-represent a hbox. Failure to do so will result in a fatal error.
+represent an \prm {hbox}. Failure to do so will result in a fatal error.
 
 Setting this callback to \type {false} is possible, but dangerous, because it is
 possible you will end up in an unfixable \quote {deadcycles loop}.
@@ -417,19 +417,20 @@
 
 \topicindex{callbacks+contributions}
 
-This callback is called whenever \LUATEX\ adds a box to a vertical list:
+This callback is called whenever \LUATEX\ adds a box to a vertical list (the
+\type {mirrored} argument is obsolete):
 
 \startfunctioncall
-function(<node> box, <string> locationcode, <number prevdepth>,
-    <boolean> mirrored)
-    return list, prevdepth
+function(<node> box, <string> locationcode, <number> prevdepth)
+    return list [, prevdepth [, checkdepth ] ]
 end
 \stopfunctioncall
 
-It is ok to return nothing in which case you also need to flush the box or deal
-with it yourself. The prevdepth is also optional. Locations are \type {box},
-\type {alignment}, \type {equation}, \type {equation_number} and \type
-{post_linebreak}.
+It is ok to return nothing or \type {nil} in which case you also need to flush
+the box or deal with it yourself. The prevdepth is also optional. Locations are
+\type {box}, \type {alignment}, \type {equation}, \type {equation_number} and
+\type {post_linebreak}. When the third argument returned is \type {true} the
+normal prevdepth correction will be applied, based on the first node.
 
 \subsection{\cbk {post_linebreak_filter}}
 
@@ -739,7 +740,7 @@
 end
 \stopfunctioncall
 
-This callback replaces the code that prints \LUATEX's when a file is opened like
+This callback replaces the code that \LUATEX\ prints when a file is opened like
 \type {(filename} for regular files. The category is a number:
 
 \starttabulate[|c|l|]
@@ -762,7 +763,7 @@
 end
 \stopfunctioncall
 
-This callback replaces the code that prints \LUATEX's when a file is closed like
+This callback replaces the code that \LUATEX\ prints when a file is closed like
 the \type {)} for regular files.
 
 \subsection{\cbk {wrapup_run}}

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-differences.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -119,6 +119,11 @@
 be used for some management related tasks. For instance you can use them to
 implement user nodes.
 
+The margin kern nodes are gone and we now use regular kern nodes for them. As a
+consequence there are two extra subtypes indicating the injected left or right
+kern. The glyph field served no real purpose so there was no reason for a special
+kind of node.
+
 The \KPSE\ library is no longer built|-|in. Because there is no backend, quite
 some file related callbacks could go away. The following file related callbacks
 remained (till now):

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -86,8 +86,8 @@
                           \NC the banner reported on the command line \NC \NR
 \NC \lpr {luatexversion}  \NC \the\luatexversion
                           \NC a combination of major and minor number \NC \NR
-\NC \lpr {luatexrevision} \NC \luatexrevision
-                          \NC the revision number, the current value is \NC \NR
+\NC \lpr {luatexrevision} \NC \the\luatexrevision
+                          \NC the revision number \NC \NR
 \LL
 \stoptabulate
 
@@ -97,24 +97,29 @@
 \startitem
     The major version is the integer result of \lpr {luatexversion} divided by
     100. The primitive is an \quote {internal variable}, so you may need to prefix
-    its use with \prm {the} depending on the context.
+    its use with \prm {the} or \prm {number} depending on the context.
 \stopitem
 \startitem
-    The minor version is the two|-|digit result of \lpr {luatexversion} modulo 100.
+    The minor version is a number running from 0 upto 99.
 \stopitem
 \startitem
-    The revision is reported by \lpr {luatexrevision}. This primitive expands to
-    a positive integer.
+    The revision is reported by \lpr {luatexrevision}. Contrary to other engines
+    in \LUAMETATEX\ is also a number so one needs to prefix it with \prm {the} or
+    \prm {number}. \footnote {In the past it always was good to prefix the
+    revision with \prm {number} anyway, just to play safe, although there have
+    for instance been times that \PDFTEX\ had funny revision indicators that at
+    some point ended up as letters due to the internal conversions.}
 \stopitem
 \startitem
-    The full version number consists of the major version, minor version and
-    revision, separated by dots.
+    The full version number consists of the major version (\type {X}), minor
+    version (\type {YY}) and revision (\type {ZZ}), separated by dots, so \type
+    {X.YY.ZZ}.
 \stopitem
 \stopitemize
 
 \stopsubsubsection
 
-The \LUAMETATEX\ version number starts at 2 in order to prevent a clash with
+The \LUAMETATEX\ version number starts at~2 in order to prevent a clash with
 \LUATEX, and the version commands are the same. This is a way to indicate that
 these projects are related.
 

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-languages.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -64,7 +64,8 @@
 {character} and a \quote {font} field, and they lived in the same memory as
 tokens did. The latter also contained a list of components, and a subtype
 indicating whether this ligature was the result of a word boundary, and it was
-stored in the same place as other nodes like boxes and kerns and glues.
+stored in the same place as other nodes like boxes and kerns and glues. In
+\LUAMETATEX\ we no longer keep the list of components with the glyph node.
 
 In \LUATEX, these two types are merged into one, somewhat larger structure called
 a \nod {glyph} node. Besides having the old character, font, and component

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-libraries.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-libraries.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-libraries.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -9,7 +9,7 @@
 \startsection[title=Introduction]
 
 The libraries can be grouped in categories like fonts, languages, \TEX,
-\METAPOST, \PDF, etc. There are however also some that are more general puspose
+\METAPOST, \PDF, etc. There are however also some that are more general purpose
 and these are discussed here.
 
 \stopsection
@@ -33,9 +33,9 @@
 \NC readinteger3      \NC (f)      \NC a 3 byte signed integer \NC \NR
 \NC readinteger4      \NC (f)      \NC a 4 byte signed integer \NC \NR
 \NC readintegertable  \NC (f,n,b)  \NC \type {n} integers of \type {b} bytes \NC \NR
-\NC readfixed2        \NC (f)      \NC a 2 byte float (used in font files) \NC \NR
-\NC readfixed4        \NC (f)      \NC a 4 byte float (used in font files) \NC \NR
-\NC read2dot14        \NC (f)      \NC a 2 byte float (used in font files) \NC \NR
+\NC readfixed2        \NC (f)      \NC a float made from a 2 byte fixed format \NC \NR
+\NC readfixed4        \NC (f)      \NC a float made from a 4 byte fixed format \NC \NR
+\NC read2dot14        \NC (f)      \NC a float made from a 2 byte in 2dot4 format \NC \NR
 \NC setposition       \NC (f,p)    \NC goto position \type {p} \NC \NR
 \NC getposition       \NC (f)      \NC get the current position \NC \NR
 \NC skipposition      \NC (f,n)    \NC skip \type {n} positions \NC \NR
@@ -45,7 +45,8 @@
 \stoptabulate
 
 When relevant there are also variants that end with \type {le} that do it the
-little endian way.
+little endian way. The fixed and dot floating points formats are found in font
+files and return \LUA\ doubles.
 
 A similar set of function as in the \type {fio} library is available in the \type
 {sio} library: \libidx {sio} {readcardinal1}, \libidx {sio} {readcardinal2},
@@ -268,6 +269,44 @@
 
 \stopsection
 
+\startsection[title=\type{xdecimal}]
+
+As an experiment \LUAMETATEX\ provides an interface to the \type {decNumber}
+library that we have on board for \METAPOST\ anyway. Apart from the usual
+support for operators there are some functions.
+
+\starttabulate[|Tw(12em)|T|T|]
+\DB name         \BC arguments  \BC results \NC \NR
+\TB
+\NC abs          \NC (a)        \NC \NC \NR
+\NC new          \NC ([n or s]) \NC \NC \NR
+\NC copy         \NC (a)        \NC \NC \NR
+\NC trim         \NC (a)        \NC \NC \NR
+\NC tostring     \NC (a)        \NC \NC \NR
+\NC tonumber     \NC (a)        \NC \NC \NR
+\NC setprecision \NC (n)        \NC \NC \NR
+\NC getprecision \NC ()         \NC \NC \NR
+\NC conj         \NC (a)        \NC \NC \NR
+\NC abs          \NC (a)        \NC \NC \NR
+\NC pow          \NC (a,b)      \NC \NC \NR
+\NC sqrt         \NC (a)        \NC \NC \NR
+\NC ln           \NC (a)        \NC \NC \NR
+\NC log          \NC (a)        \NC \NC \NR
+\NC exp          \NC (a)        \NC \NC \NR
+\NC bor          \NC (a,b)      \NC \NC \NR
+\NC bxor         \NC (a,b)      \NC \NC \NR
+\NC band         \NC (a,b)      \NC \NC \NR
+\NC shift        \NC (a,b)      \NC \NC \NR
+\NC rotate       \NC (a,b)      \NC \NC \NR
+\NC minus        \NC (a)        \NC \NC \NR
+\NC plus         \NC (a)        \NC \NC \NR
+\NC min          \NC (a,b)      \NC \NC \NR
+\NC max          \NC (a,b)      \NC \NC \NR
+\LL
+\stoptabulate
+
+\stopsection
+
 \startsection[title=\type{lfs}]
 
 The original \type {lfs} module has been adapted a bit to our needs but for
@@ -385,7 +424,7 @@
     \type {string.utfcharacters(s)}: a string with a single \UTF-8 token in it
 \stopitem
 \startitem
-    \type {string.cWharacters(s)}: a string containing one byte
+    \type {string.characters(s)}: a string containing one byte
 \stopitem
 \startitem
     \type {string.characterpairs(s)}: two strings each containing one byte or an
@@ -483,7 +522,7 @@
 \startitem
     \type {os.gettimeofday} returns the current \quote {\UNIX\ time}, but as a
     float. Keep in mind that there might be platforms where this function is
-    available.
+    not available.
 \stopitem
 
 \startitem
@@ -524,7 +563,7 @@
 
 \startsection[title={The \type {lua} library functions}]
 
-The \type {lua} library provide some general helpers.
+The \type {lua} library provides some general helpers.
 
 \startitemize
 

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-math.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -365,7 +365,7 @@
 
 In \LUATEX, the font dimension parameters that \TEX\ used in math typesetting are
 now accessible via primitive commands. In fact, refactoring of the math engine
-has resulted in many more parameters than were not accessible before.
+has resulted in turning some hard codes properties into parameters.
 
 \starttabulate
 \DB primitive name                   \BC description \NC \NR
@@ -392,7 +392,7 @@
                                        expressed in \type {percents}, so 60\% is expressed as the
                                        integer $60$ \NC \NR
 \NC \lpr {Umathstackvgap}          \NC vertical clearance between the two
-                                       elements in a \prm {atop} stack \NC \NR
+                                       elements in an \prm {atop} stack \NC \NR
 \NC \lpr {Umathstacknumup}         \NC numerator shift upward in \prm {atop} stack \NC \NR
 \NC \lpr {Umathstackdenomdown}     \NC denominator shift downward in \prm {atop} stack \NC \NR
 \NC \lpr {Umathfractionrule}       \NC the width of the rule in a \prm {over} \NC \NR
@@ -625,18 +625,15 @@
 
 \stop
 
-Method six omits the surround glue when there is (x)spacing glue present while
-method seven does the opposite, the glue is only applied when there is (x)space
-glue present too. Anything more fancy, like checking the begining or end of a
-paragraph (or edges of a box) would not be robust anyway. If you want that you
-can write a callback that runs over a list and analyzes a paragraph. Actually, in
-that case you could also inject glue (or set the properties of a math node)
-explicitly. So, these modes are in practice mostly useful for special purposes
-and experiments (they originate in a tracker item). Keep in mind that this glue
-is part of the math node and not always treated as normal glue: it travels with
-the begin and end math nodes. Also, method 6 and 7 will zero the skip related
-fields in a node when applicable in the first occasion that checks them
-(linebreaking or packaging).
+Anything more fancy, like checking the beginning or end of a paragraph (or edges
+of a box) would not be robust anyway. If you want that you can write a callback
+that runs over a list and analyzes a paragraph. Actually, in that case you could
+also inject glue (or set the properties of a math node) explicitly. So, these
+modes are in practice mostly useful for special purposes and experiments (they
+originate in a tracker item). Keep in mind that this glue is part of the math
+node and not always treated as normal glue: it travels with the begin and end
+math nodes. Also, method 6 and 7 will zero the skip related fields in a node when
+applicable in the first occasion that checks them (linebreaking or packaging).
 
 \subsection{Pairwise spacing and \lpr {Umath...spacing} commands}
 
@@ -726,7 +723,7 @@
 They are all initialized by \type {initex} to the values mentioned in the table
 in Chapter~18 of the \TEX book.
 
-Note 1: for ease of use as well as for backward compatibility, \prm {thinmuskip},
+Note 1: For ease of use as well as for backward compatibility, \prm {thinmuskip},
 \prm {medmuskip} and \prm {thickmuskip} are treated specially. In their case a
 pointer to the corresponding internal parameter is saved, not the actual \prm
 {muskip} value. This means that any later changes to one of these three
@@ -771,9 +768,9 @@
 The \type {\frozen} prefix does the magic: it injects information in the
 math list about the set parameter.
 
-In \LUATEX\ 1.10 the last setting, the \type {10pt} drop wins, but in
+In \LUATEX\ 1.10+ the last setting, the \type {10pt} drop wins, but in
 \LUAMETATEX\ you will see each local setting taking effect. The implementation
-uses a new node type, parameters nodes, so you you might encounter these in an
+uses a new node type, parameters nodes, so you might encounter these in an
 unprocessed math list. The result looks as follows:
 
 \blank \getbuffer \blank
@@ -896,7 +893,7 @@
 If you want to typeset text in math macro packages often provide something \type
 {\text} which obeys the script sizes. As the definition can be anything there is
 a good chance that the kerning doesn't come out well when used in a script. Given
-that the first glyph ends up in a \prm {hbox} we have some control over this.
+that the first glyph ends up in an \prm {hbox} we have some control over this.
 And, as a bonus we also added control over the normal sublist kerning. The \lpr
 {mathscriptboxmode} parameter defaults to~1.
 
@@ -906,7 +903,7 @@
 \NC \type {0} \NC forget about kerning \NC \NR
 \NC \type {1} \NC kern math sub lists with a valid glyph \NC \NR
 \NC \type {2} \NC also kern math sub boxes that have a valid glyph \NC \NR
-\NC \type {2} \NC only kern math sub boxes with a boundary node present\NC \NR
+\NC \type {3} \NC only kern math sub boxes with a boundary node present\NC \NR
 \LL
 \stoptabulate
 
@@ -1259,7 +1256,7 @@
 The superscript in \lpr {Uoverdelimiter} is typeset in a suitable scripted style,
 the subscript in \lpr {Uunderdelimiter} is cramped as well.
 
-These primitives accepts an option \type {width} specification. When used the
+These primitives accepts an optional \type {width} specification. When used the
 also optional keywords \type {left}, \type {middle} and \type {right} will
 determine what happens when a requested size can't be met (which can happen when
 we step to successive larger variants).
@@ -1360,11 +1357,11 @@
 Normally you will force delimiters to certain sizes by putting an empty box or
 rule next to it. The resulting delimiter will either be a character from the
 stepwise size range or an extensible. The latter can be quite differently
-positioned than the characters as it depends on the fit as well as the fact if
-the used characters in the font have depth or height. Commands like (plain \TEX
-s) \type {\big} need use this feature. In \LUATEX\ we provide a bit more control
-by three variants that support optional parameters \type {height}, \type {depth}
-and \type {axis}. The following example uses this:
+positioned than the characters as it depends on the fit as well as the fact
+whether the used characters in the font have depth or height. Commands like
+(plain \TEX s) \type {\big} need to use this feature. In \LUATEX\ we provide a bit
+more control by three variants that support optional parameters \type {height},
+\type {depth} and \type {axis}. The following example uses this:
 
 \startbuffer
 \Uleft   height 30pt depth 10pt      \Udelimiter "0 "0 "000028
@@ -1429,7 +1426,7 @@
 [2] [3] [4]
 \stoptyping
 
-These commands are provides as convenience. Before they come available you could
+These commands are provided as convenience. Before they come available you could
 do the following:
 
 \starttyping
@@ -1511,7 +1508,7 @@
 $
 \stopbuffer
 
-\typebuffer
+\typebuffer[script]
 
 results in \inlinebuffer[script].
 
@@ -1534,7 +1531,7 @@
 \topicindex {math+flattening}
 
 The \TEX\ math engine collapses \type {ord} noads without sub- and superscripts
-and a character as nucleus. and which has the side effect that in \OPENTYPE\ mode
+and a character as nucleus, which has the side effect that in \OPENTYPE\ mode
 italic corrections are applied (given that they are enabled).
 
 \startbuffer[sample]

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-metapost.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -30,8 +30,8 @@
 <mpinstance> mp = mplib.new({...})
 \stopfunctioncall
 
-This creates the \type {mp} instance object. The argument hash can have a number
-of different fields, as follows:
+This creates the \type {mp} instance object. The argument is a hash table that
+can have a number of different fields, as follows:
 
 \starttabulate[|l|l|pl|pl|]
 \DB name               \BC type     \BC description              \BC default           \NC \NR
@@ -236,10 +236,10 @@
 When the boundingbox represents a \quote {negated rectangle}, i.e.\ when the
 first set of coordinates is larger than the second set, the picture is empty.
 
-Graphical objects come in various types that each has a different list of
-accessible values. The types are: \type {fill}, \type {outline}, \type {text},
-\type {start_clip}, \type {stop_clip}, \type {start_bounds}, \type {stop_bounds},
-\type {special}.
+Graphical objects come in various types: \type {fill}, \type {outline}, \type
+{text}, \type {start_clip}, \type {stop_clip}, \type {start_bounds}, \type
+{stop_bounds}, \type {special}. Each type has a different list of accessible
+values.
 
 There is a helper function (\type {mplib.fields(obj)}) to get the list of
 accessible values for a particular object, but you can just as easily use the
@@ -395,9 +395,9 @@
 
 \subsection{Dashes}
 
-Each \type {dash} is two-item hash, using the same model as \POSTSCRIPT\ for the
-representation of the dashlist. \type {dashes} is an array of \quote {on} and
-\quote {off}, values, and \type {offset} is the phase of the pattern.
+Each \type {dash} is a hash with two items. We use the same model as \POSTSCRIPT\
+for the representation of the dashlist. \type {dashes} is an array of \quote {on}
+and \quote {off}, values, and \type {offset} is the phase of the pattern.
 
 \starttabulate[|l|l|p|]
 \DB field  \BC type \BC explanation \NC \NR

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-nodes.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -459,7 +459,7 @@
 \NC \type{left}             \NC number  \NC the frozen \type {\lefthyphenmnin} value \NC \NR
 \NC \type{right}            \NC number  \NC the frozen \type {\righthyphenmnin} value \NC \NR
 \NC \type{uchyph}           \NC boolean \NC the frozen \prm {uchyph} value \NC \NR
-\NC \type{components}       \NC node    \NC pointer to ligature components \NC \NR
+\NC \type{state}            \NC number  \NC a user field (replaces the component list) \NC \NR
 \NC \type{xoffset}          \NC number  \NC a virtual displacement in horizontal direction \NC \NR
 \NC \type{yoffset}          \NC number  \NC a virtual displacement in vertical direction \NC \NR
 \NC \type{width}            \NC number  \NC the (original) width of the character \NC \NR
@@ -472,11 +472,8 @@
 
 The \type {width}, \type {height} and \type {depth} values are read|-|only. The
 \type {expansion_factor} is assigned in the par builder and used in the backend.
+Valid bits for the \type {subtype} field are:
 
-A warning: never assign a node list to the components field unless you are sure
-its internal link structure is correct, otherwise an error may be result. Valid
-bits for the \type {subtype} field are:
-
 \starttabulate[|c|l|]
 \DB bit \BC meaning   \NC \NR
 \TB
@@ -583,26 +580,6 @@
 
 \stopsubsection
 
-\startsubsection[title={\nod {marginkern} nodes}]
-
-\topicindex {nodes+paragraphs}
-\topicindex {paragraphs}
-\topicindex {protrusion}
-
-Margin kerns result from protrusion and have: \showfields {margin_kern}.
-
-\starttabulate[|l|l|p|]
-\DB field          \BC type   \BC explanation \NC \NR
-\TB
-\NC \type{subtype} \NC number \NC \showsubtypes{marginkern} \NC \NR
-\NC \type{attr}    \NC node   \NC list of attributes \NC \NR
-\NC \type{width}   \NC number \NC the advance of the kern \NC \NR
-\NC \type{glyph}   \NC node   \NC the glyph to be used \NC \NR
-\LL
-\stoptabulate
-
-\stopsubsection
-
 \startsubsection[title={Whatsits}]
 
 A whatsit node is a real simple one and it only has a subtype. It is even less
@@ -950,8 +927,7 @@
 
 \startitem
     When you remove a node, make sure that when this is permanent, you also free
-    the node or list. When you free a node its components are checked and when
-    they are nodes themselves they are also freed.
+    the node or list.
 \stopitem
 
 \startitem
@@ -2149,7 +2125,6 @@
 %supported {find_node}               \nop \yes \relax
 \supported {first_glyph}             \nop \yes \yes
 \supported {flatten_discretionaries} \nop \yes \yes
-%supported {flush_components}        \nop \yes \relax
 \supported {flush_list}              \yes \yes \relax
 \supported {flush_node}              \yes \yes \relax
 \supported {free}                    \yes \yes \relax
@@ -2160,7 +2135,7 @@
 \supported {getboth}                 \nop \yes \relax
 \supported {getbox}                  \nop \yes \relax
 \supported {getchar}                 \nop \yes \relax
-\supported {getcomponents}           \nop \yes \relax
+\supported {getstate}                \nop \yes \relax
 \supported {getdata}                 \nop \yes \relax
 \supported {getdepth}                \nop \yes \relax
 \supported {getdirection}            \nop \yes \relax
@@ -2228,7 +2203,7 @@
 \supported {setboth}                 \nop \yes \relax
 \supported {setbox}                  \nop \yes \relax
 \supported {setchar}                 \nop \yes \relax
-\supported {setcomponents}           \nop \yes \relax
+\supported {setstate}                \nop \yes \relax
 \supported {setdata}                 \nop \yes \relax
 \supported {setdepth}                \nop \yes \relax
 \supported {setdirection}            \nop \yes \relax
@@ -2291,7 +2266,7 @@
 
 Some of the getters and setters handle multiple node types, given that the field
 is relevant. In that case, some field names are considered similar (like \type
-{kern} and \type {width}, or \type {data} and \type {value}. In retrospect we
+{kern} and \type {width}, or \type {data} and \type {value}). In retrospect we
 could have normalized field names better but we decided to stick to the original
 (internal) names as much as possible. After all, at the \LUA\ end one can easily
 create synonyms.
@@ -2372,10 +2347,10 @@
 \libindex{set_properties_mode}
 
 Attributes are a convenient way to relate extra information to a node. You can
-assign them at the \TEX\ end as well as at the \LUA\ end and and consult them at
-the \LUA\ end. One big advantage is that they obey grouping. They are linked
-lists and normally checking for them is pretty efficient, even if you use a lot
-of them. A macro package has to provide some way to manage these attributes at the
+assign them at the \TEX\ end as well as at the \LUA\ end and consult them at the
+\LUA\ end. One big advantage is that they obey grouping. They are linked lists
+and normally checking for them is pretty efficient, even if you use a lot of
+them. A macro package has to provide some way to manage these attributes at the
 \TEX\ end because otherwise clashes in their usage can occur.
 
 Each node also can have a properties table and you can assign values to this
@@ -2502,7 +2477,7 @@
 copy gets its own table with the original table as metatable. If you use the
 generic font loader the mode is enabled that way.
 
-A few more xperiments were done. For instance: copy attributes to the properties
+A few more experiments were done. For instance: copy attributes to the properties
 so that we have fast access at the \LUA\ end. In the end the overhead is not
 compensated by speed and convenience, in fact, attributes are not that slow when
 it comes to accessing them. So this was rejected.

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-pdf.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-pdf.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-pdf.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -148,7 +148,7 @@
 \libindex {getbox}
 
 A specific page can conveniently be reached with the next command, which
-returns a dictionary. The first argument is to be a page dictionary.
+returns a dictionary.
 
 \starttyping
 <pdfe dictionary> = pdfe.getpage(<pdfe document>,pagenumber)
@@ -185,7 +185,7 @@
 
 \stopsubsection
 
-\startsubsection[title={\type {get[from][dictionary|array|stream]}}]
+\startsubsection[title={\type {get[dictionary|array|stream]}}]
 
 \libindex {getdictionary} \libindex {getfromdictionary}
 \libindex {getarray}      \libindex {getfromarray}
@@ -333,7 +333,7 @@
 
 \libindex {new}
 
-The \type {pdfe.new} that takes three arguments:
+The \type {pdfe.new} function takes three arguments:
 
 \starttabulate
 \DB value           \BC explanation      \NC \NR
@@ -343,12 +343,11 @@
 \NC \type {length}  \NC this is the length of the stream in bytes (the stream can
                         have embedded zeros) \NC \NR
 \NC \type {name}    \NC optional, this is a unique identifier that is used for
-                        hashing the stream, so that multiple doesn't use more
-                        memory \NC \NR
+                        hashing the stream \NC \NR
 \LL
 \stoptabulate
 
-The third argument is optional. When it is not given the function will return an
+The third argument is optional. When it is not given the function will return a
 \type {pdfe} document object as with a regular file, otherwise it will return a
 filename that can be used elsewhere (e.g.\ in the image library) to reference the
 stream as pseudo file.
@@ -357,7 +356,7 @@
 come from a library) you can also pass a \LUA\ string, in which case the given
 length is (at most) the string length.
 
-The function returns an \type {pdfe} object and a string. The string can be used in
+The function returns a \type {pdfe} object and a string. The string can be used in
 the \type {img} library instead of a filename. You need to prevent garbage
 collection of the object when you use it as image (for instance by storing it
 somewhere).

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -18,7 +18,7 @@
 Some of the \PDFTEX\ support primitives have been around from the start but when
 \LUA\ integration became better and when a token scanner library was added, not
 all of those made sense as primitives. In previous chapters we already mentioned
-what is gone from the core. Deep down some more has changes but not all is
+what is gone from the core. Deep down some more has changed but not all is
 reflected at the primitive level. Because there is still a considerable amount of
 new primitives, a summary is given below.
 

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -24,7 +24,7 @@
 <string> s = lua.startupfile
 \stoptyping
 
-This returns the \LUA\ version identifier string. The value is currently
+This returns the \LUA\ version identifier string. The value currently is
 \directlua {tex.print(lua.version)}.
 
 \stopsubsection
@@ -120,7 +120,7 @@
 accessors are:
 
 \startfunctioncall
-lua.setluaname(<string> s,<number> n])
+lua.setluaname(<string> s,<number> n)
 <string> s = lua.getluaname(<number> n)
 \stopfunctioncall
 
@@ -305,9 +305,7 @@
 \type {tex.get} you get the width of the glue and when you pass \type {true} you
 get all five values. Otherwise you get a node which is a copy of the internal
 value so you are responsible for its freeing at the \LUA\ end. When you set a
-glue quantity you can either pass a \nod {glue_spec} or upto five numbers. If
-you pass \type {true} to \type {get} you get 5 values returned for a glue and
-when you pass \type {false} you only get the width returned.
+glue quantity you can either pass a \nod {glue_spec} or upto five numbers.
 
 \subsubsection{Integer parameters}
 
@@ -738,10 +736,10 @@
 Again the glue variants are not using the \nod {glue-spec} userdata nodes. The
 \type {setglue} function accepts upto 5 arguments: width, stretch, shrink,
 stretch order and shrink order and the \type {getglue} function reports them,
-unless the second argument is \type {false} in which care only the width is
+unless the second argument is \type {false} in which case only the width is
 returned.
 
-Here is an example usign a threesome:
+Here is an example using a threesome:
 
 \startfunctioncall
 local d = tex.getdimen("foo")
@@ -1207,7 +1205,7 @@
     from eating spaces as result of interpreting the line. For example, in
 
     \starttyping
-    before\directlua{tex.sprint("\\relax")tex.sprint(" inbetween")}after
+    before\directlua{tex.sprint("\\relax")tex.sprint(" in between")}after
     \stoptyping
 
     the space before \type {in between} will be gobbled as a result of the \quote
@@ -1426,7 +1424,7 @@
 tex.setlinenumber(10,true)
 \stopfunctioncall
 
-This might be handy when you have a callback that read numbers from a file and
+This might be handy when you have a callback that reads numbers from a file and
 combines them in one line (in which case an error message probably has to refer
 to the original line). Interference with \TEX's internal handling of numbers is
 of course possible.
@@ -1470,7 +1468,7 @@
 \libindex{setinteraction}
 \libindex{getinteraction}
 
-The engine can in one of four modes:
+The engine can be in one of four modes:
 
 \starttabulate[|lT|l|pl|]
 \DB value \NC mode      \BC meaning \NC \NR
@@ -1862,7 +1860,7 @@
 For practical reasons \LUATEX\ has its own random number generator. The original
 \LUA\ random function is available as \typ {tex.lua_math_random}. You can
 initialize with a new seed with \type {init_rand} (\typ {lua_math_randomseed} is
-equivalent to this one.
+equivalent to this one).
 
 There are three generators: \type {normal_rand} (no argument is used), \type
 {uniform_rand} (takes a number that will get rounded before being used) and \type
@@ -1989,7 +1987,7 @@
 texio.write_nl(<string> s, ...)
 \stopfunctioncall
 
-This function behaves like \type {texio.write}, but make sure that the given
+This function behaves like \type {texio.write}, but makes sure that the given
 strings will appear at the beginning of a new line. You can pass a single empty
 string if you only want to move to the next line.
 
@@ -2008,11 +2006,11 @@
 
 \libindex{closeinput}
 
-This function that should be used with care. It acts as \prm {endinput} but at
-the \LUA\ end. You can use it to (sort of) force a jump back to \TEX. Normally a
-\LUA\ will just collect prints and at the end bump an input level and flush these
-prints. This function can help you stay at the current level but you need to know
-what you're doing (or more precise: what \TEX\ is doing with input).
+This function should be used with care. It acts as \prm {endinput} but at the
+\LUA\ end. You can use it to (sort of) force a jump back to \TEX. Normally a
+\LUA\ call will just collect prints and at the end bump an input level and flush
+these prints. This function can help you stay at the current level but you need
+to know what you're doing (or more precise: what \TEX\ is doing with input).
 
 \stopsubsection
 
@@ -2043,7 +2041,7 @@
 The token library provides means to intercept the input and deal with it at the
 \LUA\ level. The library provides a basic scanner infrastructure that can be used
 to write macros that accept a wide range of arguments. This interface is on
-purpose kept general and as performance is quite ok. One can build additional
+purpose kept general and as performance is quite okay so one can build additional
 parsers without too much overhead. It's up to macro package writers to see how
 they can benefit from this as the main principle behind \LUATEX\ is to provide a
 minimal set of tools and no solutions. The scanner functions are probably the
@@ -2060,9 +2058,9 @@
 \NC \type{scan_int}       \NC                    \NC returns an integer \NC \NR
 \NC \type{scan_real}      \NC                    \NC returns a number from e.g.\ \type {1},  \type {1.1}, \type {.1} with optional collapsed signs \NC \NR
 \NC \type{scan_float}     \NC                    \NC returns a number from e.g.\ \type {1},  \type {1.1}, \type {.1}, \type {1.1E10}, , \type {.1e-10} with optional collapsed signs \NC \NR
-\NC \type{scan_dimen}     \NC infinity, mu-units \NC returns a number representing a dimension and or two numbers being the filler and order \NC \NR
+\NC \type{scan_dimen}     \NC infinity, mu-units \NC returns a number representing a dimension or two numbers being the filler and order \NC \NR
 \NC \type{scan_glue}      \NC mu-units           \NC returns a glue spec node \NC \NR
-\NC \type{scan_toks}      \NC definer, expand    \NC returns a table of tokens tokens \NC \NR
+\NC \type{scan_toks}      \NC definer, expand    \NC returns a table of tokens \NC \NR
 \NC \type{scan_code}      \NC bitset             \NC returns a character if its category is in the given bitset (representing catcodes) \NC \NR
 \NC \type{scan_string}    \NC                    \NC returns a string given between \type {{}}, as \type {\macro} or as sequence of characters with catcode 11 or 12 \NC \NR
 \NC \type{scan_argument}  \NC                    \NC this one is simular to \type {scanstring} but also accepts a \type {\cs}
@@ -2074,7 +2072,7 @@
 \stoptabulate
 
 The scanners can be considered stable apart from the one scanning for a token.
-The \type {scan_code} function takes an optional number, the \type {keyword}
+The \type {scan_code} function takes an optional number, the \type {scan_keyword}
 function a normal \LUA\ string. The \type {infinity} boolean signals that we also
 permit \type {fill} as dimension and the \type {mu-units} flags the scanner that
 we expect math units. When scanning tokens we can indicate that we are defining a
@@ -2236,7 +2234,7 @@
 \NC \type {command}    \NC a number representing the internal command number \NC \NR
 \NC \type {cmdname}    \NC the type of the command (for instance the catcode in case of a
                            character or the classifier that determines the internal
-                           treatment \NC \NR
+                           treatment) \NC \NR
 \NC \type {csname}     \NC the associated control sequence (if applicable) \NC \NR
 \NC \type {id}         \NC the unique id of the token \NC \NR
 \NC \type {tok}        \NC the full token number as stored in \TEX \NC \NR
@@ -2378,10 +2376,32 @@
 token.put_next ( t3, t4 )
 \stoptyping
 
-When we scan \type {wxyz!} we get \type {yzwx!} back. The argument is either a table
-with tokens or a list of tokens. The \type {token.expand} function will trigger
-expansion but what happens really depends on what you're doing where.
+When we scan \type {wxyz!} we get \type {yzwx!} back. The argument is either a
+table with tokens or a list of tokens. The \type {token.expand} function will
+trigger expansion but what happens really depends on what you're doing where.
 
+This putter is actually a bit more flexible because the following input also
+works out okay:
+
+\startbuffer
+\def\foo#1{[#1]}
+
+\directlua {
+    local list = { 101, 102, 103, token.create("foo"), "{abracadabra}" }
+    token.put_next("(the)")
+    token.put_next(list)
+    token.put_next("(order)")
+    token.put_next(unpack(list))
+    token.put_next("(is reversed)")
+}
+\stopbuffer
+
+\typebuffer
+
+We get this: \blank {\tt \inlinebuffer} \blank So, strings get converted to
+individual tokens according to the current catcode regime and numbers become
+characters also according to this regime.
+
 \stopsubsection
 
 \startsubsection[title={Nota bene}]
@@ -2390,6 +2410,8 @@
 like \TEX\ does: expanding, changing modes and doing things as it goes. When we
 scan with \LUA\ we just pick up tokens. Say that we have:
 
+\pushmacro\bar \let\bar\undefined
+
 \starttyping
 \bar
 \stoptyping
@@ -2472,6 +2494,8 @@
 that can be used and garbage collected, but it is basically the same one,
 representing an undefined control sequence.
 
+\popmacro\bar
+
 \stopsubsection
 
 \stopsection

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/tools/tools-mkiv.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/tools/tools-mkiv.tex	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/tools/tools-mkiv.tex	2020-03-16 21:11:40 UTC (rev 54364)
@@ -373,8 +373,8 @@
 For quite a while we shipped so called \CONTEXT\ minimals. These zip files
 contained only the resources and programs that made sense for running \CONTEXT.
 Nowadays the minimals are installed and synchronized via internet. \footnote
-{This project was triggered by Mojca Miklavec who is also charge of this bit of
-the \CONTEXT\ infrastructure. More information can be found at \type
+{This project was triggered by Mojca Miklavec who is also in charge of this bit
+of the \CONTEXT\ infrastructure. More information can be found at \type
 {contextgarden.net}.} You can just run the installer again and no additional
 commands are needed. In the console you will see several calls to \sMTXRUN\ and
 \sLUATOOLS\ fly by.
@@ -415,7 +415,7 @@
 
 \typefile[ntyping]{tools-mkiv-help.tmp}
 
-There are few exert options too:
+There are few expert options too:
 
 \ctxlua{os.execute("context --expert > tools-mkiv-help.tmp")}
 
@@ -451,7 +451,7 @@
 
 \startsection[title={Stubs}]
 
-As the tools are written in the \LUA\ language we need a \LUA\ interpreter and or
+As the tools are written in the \LUA\ language we need a \LUA\ interpreter and of
 course we use \LUATEX\ itself. On \UNIX\ we can copy \sLUATOOLS\ and \sMTXRUN\ to
 files in the binary path with the same name but without suffix. Starting them in
 another way is a waste of time, especially when \sKPSEWHICH\ is used to find
@@ -498,12 +498,11 @@
 You can copy \type {mtxrun.exe} to for instance \type {context.exe} and it will
 still use \sMTXRUN\ for locating the right script. It also takes care of mapping
 \sTEXMFSTART\ to \sMTXRUN. So we've removed the intermediate \type {cmd} step,
-can not run the script as any program, and most of all, we're as efficient as can
-be. Of course this program is only meaningful for the \CONTEXT\ approach to
-tools.
+can run the script as any program, and most of all, we're as efficient as can be.
+Of course this program is only meaningful for the \CONTEXT\ approach to tools.
 
 It may all sound more complex than it is but once it works users will not notice
-those details. Als, in practice not that much has changed in running the tools
+those details. Also, in practice not that much has changed in running the tools
 between \MKII\ and \MKIV\ as we've seen no reason to change the methods.
 
 \stopsection
@@ -562,11 +561,10 @@
 alternate behaviour). Since this also affects the \LUA\ code within \sMTXRUN\
 itself, it makes sense to list these options first.
 
-Getting information on trackers, directives and experiments. Trackers enable more
-extensive status messages on the console or in \CONTEXT\ additional visual clues.
-Directives change behaviour that are not part of the official interface and have
-no corresponding commands. Experiments are like directives but not official
-(yet).
+Trackers enable more extensive status messages on the console or in \CONTEXT\
+additional visual clues. Directives change behaviour that is not part of the
+official interface and have no corresponding commands. Experiments are like
+directives but not official (yet).
 
 \startoptions
     \option
@@ -615,7 +613,7 @@
 of this article, but you can look them up in the \CONTEXT\ source by searching
 for \typ {directives.register} and \typ {trackers.register}.
 
-In verbose mode, \sMTXRUN\ itself gives more messages, and it also \typ
+In verbose mode, \sMTXRUN\ itself gives more messages, and it also enables \typ
 {resolvers.locating}, which is a tracker itself:
 
 \startoptions
@@ -671,11 +669,13 @@
         {use given texmf tree (default file: \type {setuptex.tmf})}
 \stopoptions
 
+We don't provide such a \type {.tmf} file in the distribution.
+
 \stopsubsection
 
 \startsubsection[title=Options for finding files and reporting configurations]
 
-Once the configuration setup is done, it makes sense to have a bunch or options
+Once the configuration setup is done, it makes sense to have a bunch of options
 to use and|/|or query the configuration.
 
 \startoptions
@@ -808,7 +808,7 @@
 works. Scripts are looked for in the local path, and in whatever directories the
 configuration variable \type {LUAINPUTS} points to.
 
-The \type {--execute} options exists mostly for the non||\LUA\ {\MKII} scripts
+The \type {--execute} option exists mostly for the non||\LUA\ {\MKII} scripts
 that still exist in the distribution. It will try to find a matching interpreter
 for non||\LUA\ scripts, and it is aware of a number of distribution||supplied
 scripts so that if you specify \type {--execute texexec}, it knows that what you
@@ -1211,7 +1211,7 @@
 end
 \stoptyping
 
-An finally, identify the current script, followed by handling the provided
+And finally, identify the current script, followed by handling the provided
 options (usually with an \type {if}||\type {else} statement).
 
 \starttyping
@@ -1229,11 +1229,11 @@
 \startsubsection[title=Script environment]
 
 \sMTXRUN\ includes lots of the internal \LUA\ helper libraries from \CONTEXT. We
-actually maintains a version of the script without all those libraries included,
+actually maintain a version of the script without all those libraries included,
 and before every (beta) \CONTEXT\ release, an amalgamated version of \sMTXRUN\ is
-added to the distribution. In the merging process, most all comments are stripped
-from the embedded libraries, so if you want to know details, it is better to look
-in the original \LUA\ source file.
+added to the distribution. In the merging process, all comments are stripped from
+the embedded libraries, so if you want to know details, it is better to look in
+the original \LUA\ source file.
 
 Inside \sMTXRUN, the full list of embedded libraries can be queried via the array
 \type {own.libs}:
@@ -1259,8 +1259,8 @@
 option and also allows the non||amalgamated version to run (since otherwise \type
 {--selfmerge} could not be bootstrapped).
 
-\sMTXRUN\ offers a programming environment that makes it easy to write \LUA\ a
-scripts. The most important element of that environment is a \LUA\ table that is
+\sMTXRUN\ offers a programming environment that makes it easy to write \LUA\
+script. The most important element of that environment is a \LUA\ table that is
 conveniently called \type {environment} (\type {util-env} does the actual work of
 setting that up).
 
@@ -1379,7 +1379,7 @@
     {Locates and compiles a \LUA\ file, returning its contents as data.}
 \mtxrunenv
     {make_format(name,arguments)}
-    {Creates a format file and stores in in the \CONTEXT\ cache, used by \type
+    {Creates a format file and stores it in the \CONTEXT\ cache, used by \type
      {mtxrun --make}.}
 \mtxrunenv
     {relativepath(path,root)}

Modified: trunk/Master/texmf-dist/doc/man/man1/context.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/luatools.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-babel.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-base.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-bibtex.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-cache.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-chars.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-check.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-colors.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-context.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-dvi.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-epub.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-evohome.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-fcd.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-flac.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-fonts.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-grep.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-interface.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-metapost.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-modules.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-package.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-patterns.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-pdf.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-plain.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-profile.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-rsync.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-scite.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-server.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-texworks.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-timing.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-tools.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-unicode.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-unzip.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-update.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-vscode.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-watch.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtx-youless.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/texexec.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/texmfstart.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/metapost/context/base/mpii/mp-tool.mpii
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpii/mp-tool.mpii	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/metapost/context/base/mpii/mp-tool.mpii	2020-03-16 21:11:40 UTC (rev 54364)
@@ -566,7 +566,7 @@
             addto currentpicture also pattern ;
             addto currentpicture also shape ;
         fi ;
-        currentpicture := currentpicture shifted - centrum ;
+        currentpicture := currentpicture shifted centrum ;
         endgroup ;
     )
 enddef;

Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-lmtx.mpxl
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-lmtx.mpxl	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-lmtx.mpxl	2020-03-16 21:11:40 UTC (rev 54364)
@@ -2066,7 +2066,7 @@
 
 newinternal svgforcecmyk ; svgforcecmyk := 0 ;
 
-vardef svgcolor(expr r,g,b) =
+vardef svgcolor(expr r, g, b) =
     if svgforcecmyk > 0 :
         (1-r,1-g,1-b,0) % simple: no black component, kind of ok for emoji
     else :
@@ -2074,6 +2074,10 @@
     fi
 enddef ;
 
+vardef svgcmyk(expr c, m, y, k) =
+    (c,m,y,k)
+enddef ;
+
 vardef svggray(expr s) =
     s
 enddef ;
@@ -2081,6 +2085,7 @@
 presetparameters "svg" [
     filename = "",
     fontname = "",
+    colormap = "",
   % unicode  = 0,
     width    = 0,
     height   = 0,

Modified: trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tool.mpiv
===================================================================
--- trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tool.mpiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/metapost/context/base/mpiv/mp-tool.mpiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -641,7 +641,7 @@
             addto currentpicture also pattern ;
             addto currentpicture also shape ;
         fi ;
-        currentpicture := currentpicture shifted - centrum ;
+        currentpicture := currentpicture shifted centrum ;
         endgroup ;
     )
 enddef;

Modified: trunk/Master/texmf-dist/scripts/context/lua/mtxrun.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/context/lua/mtxrun.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/scripts/context/lua/mtxrun.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -3806,7 +3806,7 @@
 
 package.loaded["l-os"] = package.loaded["l-os"] or true
 
--- original size: 19102, stripped down to: 10192
+-- original size: 19120, stripped down to: 10208
 
 if not modules then modules={} end modules ['l-os']={
  version=1.001,
@@ -4101,7 +4101,7 @@
 end
 local d
 function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ d=d or ((tonumber(date("%H")) or 0)-(tonumber(date("!%H")) or 0))
  if delta then
   if d>0 then
    return format("+%02i:00",d)
@@ -6563,7 +6563,7 @@
 
 package.loaded["util-str"] = package.loaded["util-str"] or true
 
--- original size: 45188, stripped down to: 22734
+-- original size: 45153, stripped down to: 22734
 
 if not modules then modules={} end modules ['util-str']={
  version=1.001,
@@ -10079,7 +10079,7 @@
 
 package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
 
--- original size: 25959, stripped down to: 14893
+-- original size: 26186, stripped down to: 14893
 
 
 local socket=socket or require("socket")
@@ -13961,7 +13961,7 @@
 
 package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
 
--- original size: 9973, stripped down to: 7492
+-- original size: 10184, stripped down to: 7500
 
 if not modules then modules={} end modules ['trac-inf']={
  version=1.001,
@@ -13995,10 +13995,11 @@
 end
 local ticks=clock
 local seconds=function(n) return n or 0 end
-if lua.getpreciseticks then
+if os.type~="windows" then
+elseif lua.getpreciseticks then
  ticks=lua.getpreciseticks
  seconds=lua.getpreciseseconds
-elseif FFISUPPORTED and ffi and os.type=="windows" then
+elseif FFISUPPORTED then
  local okay,kernel=pcall(ffi.load,"kernel32")
  if kernel then
   local tonumber=ffi.number or tonumber
@@ -14136,12 +14137,12 @@
   end)
   if LUATEXENGINE=="luametatex" then
    register("used engine",function()
-    return format("%s version %s, functionality level %s, format id %s",
-     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID)
+    return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID,status.used_compiler)
    end)
   else
    register("used engine",function()
-    return format("%s version %s with functionality level %s, banner: %s",
+    return format("%s version: %s, functionality level: %s, banner: %s",
      LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
    end)
   end
@@ -14149,7 +14150,7 @@
    return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
   end)
   register("callbacks",statistics.callbacks)
-  if TEXENGINE=="luajittex" and JITSUPPORTED then
+  if JITSUPPORTED then
    local jitstatus=jit.status
    if jitstatus then
     local jitstatus={ jitstatus() }
@@ -14183,7 +14184,7 @@
 end
 function statistics.memused() 
  local round=math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB)",
+ return format("%s MB, ctx: %s MB, max: %s MB",
   round(collectgarbage("count")/1000),
   round(status.luastate_bytes/1000000),
   status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
@@ -20789,7 +20790,7 @@
 
 package.loaded["data-ini"] = package.loaded["data-ini"] or true
 
--- original size: 11019, stripped down to: 7086
+-- original size: 10847, stripped down to: 7086
 
 if not modules then modules={} end modules ['data-ini']={
  version=1.001,
@@ -25784,7 +25785,7 @@
 
 package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
 
--- original size: 13964, stripped down to: 10026
+-- original size: 13843, stripped down to: 9991
 
 if not modules then modules={} end modules ['luat-fmt']={
  version=1.001,
@@ -25821,9 +25822,6 @@
  if arguments.errors then
   flags[#flags+1]="--c:errors"
  end
- if arguments.jit then
-  flags[#flags+1]="--c:jiton"
- end
  if arguments.ansi then
   flags[#flags+1]="--c:ansi"
  end
@@ -25991,9 +25989,9 @@
  if silent then
   specification.redirect="> temp.log"
  end
- statistics.starttiming()
+ statistics.starttiming("format")
  local result=runner(specification)
- local runtime=statistics.stoptiming()
+ statistics.stoptiming("format")
  if silent then
   os.remove("temp.log")
  end
@@ -26011,7 +26009,7 @@
  report_format("secondary flags  : %s",secondaryflags)
   end
  report_format("context file     : %s",fulltexsourcename)
- report_format("run time         : %.3f seconds",runtime)
+ report_format("run time         : %.3f seconds",statistics.elapsed("format"))
  report_format("return value     : %s",result==0 and "okay" or "error")
  report_format()
  lfs.chdir(startupdir)
@@ -26117,8 +26115,8 @@
 
 -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
 -- skipped libraries : -
--- original bytes    : 1038245
--- stripped bytes    : 409841
+-- original bytes    : 1038373
+-- stripped bytes    : 409980
 
 -- end library merge
 

Modified: trunk/Master/texmf-dist/scripts/context/stubs/mswin/mtxrun.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/context/stubs/mswin/mtxrun.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/scripts/context/stubs/mswin/mtxrun.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -3806,7 +3806,7 @@
 
 package.loaded["l-os"] = package.loaded["l-os"] or true
 
--- original size: 19102, stripped down to: 10192
+-- original size: 19120, stripped down to: 10208
 
 if not modules then modules={} end modules ['l-os']={
  version=1.001,
@@ -4101,7 +4101,7 @@
 end
 local d
 function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ d=d or ((tonumber(date("%H")) or 0)-(tonumber(date("!%H")) or 0))
  if delta then
   if d>0 then
    return format("+%02i:00",d)
@@ -6563,7 +6563,7 @@
 
 package.loaded["util-str"] = package.loaded["util-str"] or true
 
--- original size: 45188, stripped down to: 22734
+-- original size: 45153, stripped down to: 22734
 
 if not modules then modules={} end modules ['util-str']={
  version=1.001,
@@ -10079,7 +10079,7 @@
 
 package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
 
--- original size: 25959, stripped down to: 14893
+-- original size: 26186, stripped down to: 14893
 
 
 local socket=socket or require("socket")
@@ -13961,7 +13961,7 @@
 
 package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
 
--- original size: 9973, stripped down to: 7492
+-- original size: 10184, stripped down to: 7500
 
 if not modules then modules={} end modules ['trac-inf']={
  version=1.001,
@@ -13995,10 +13995,11 @@
 end
 local ticks=clock
 local seconds=function(n) return n or 0 end
-if lua.getpreciseticks then
+if os.type~="windows" then
+elseif lua.getpreciseticks then
  ticks=lua.getpreciseticks
  seconds=lua.getpreciseseconds
-elseif FFISUPPORTED and ffi and os.type=="windows" then
+elseif FFISUPPORTED then
  local okay,kernel=pcall(ffi.load,"kernel32")
  if kernel then
   local tonumber=ffi.number or tonumber
@@ -14136,12 +14137,12 @@
   end)
   if LUATEXENGINE=="luametatex" then
    register("used engine",function()
-    return format("%s version %s, functionality level %s, format id %s",
-     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID)
+    return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID,status.used_compiler)
    end)
   else
    register("used engine",function()
-    return format("%s version %s with functionality level %s, banner: %s",
+    return format("%s version: %s, functionality level: %s, banner: %s",
      LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
    end)
   end
@@ -14149,7 +14150,7 @@
    return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
   end)
   register("callbacks",statistics.callbacks)
-  if TEXENGINE=="luajittex" and JITSUPPORTED then
+  if JITSUPPORTED then
    local jitstatus=jit.status
    if jitstatus then
     local jitstatus={ jitstatus() }
@@ -14183,7 +14184,7 @@
 end
 function statistics.memused() 
  local round=math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB)",
+ return format("%s MB, ctx: %s MB, max: %s MB",
   round(collectgarbage("count")/1000),
   round(status.luastate_bytes/1000000),
   status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
@@ -20789,7 +20790,7 @@
 
 package.loaded["data-ini"] = package.loaded["data-ini"] or true
 
--- original size: 11019, stripped down to: 7086
+-- original size: 10847, stripped down to: 7086
 
 if not modules then modules={} end modules ['data-ini']={
  version=1.001,
@@ -25784,7 +25785,7 @@
 
 package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
 
--- original size: 13964, stripped down to: 10026
+-- original size: 13843, stripped down to: 9991
 
 if not modules then modules={} end modules ['luat-fmt']={
  version=1.001,
@@ -25821,9 +25822,6 @@
  if arguments.errors then
   flags[#flags+1]="--c:errors"
  end
- if arguments.jit then
-  flags[#flags+1]="--c:jiton"
- end
  if arguments.ansi then
   flags[#flags+1]="--c:ansi"
  end
@@ -25991,9 +25989,9 @@
  if silent then
   specification.redirect="> temp.log"
  end
- statistics.starttiming()
+ statistics.starttiming("format")
  local result=runner(specification)
- local runtime=statistics.stoptiming()
+ statistics.stoptiming("format")
  if silent then
   os.remove("temp.log")
  end
@@ -26011,7 +26009,7 @@
  report_format("secondary flags  : %s",secondaryflags)
   end
  report_format("context file     : %s",fulltexsourcename)
- report_format("run time         : %.3f seconds",runtime)
+ report_format("run time         : %.3f seconds",statistics.elapsed("format"))
  report_format("return value     : %s",result==0 and "okay" or "error")
  report_format()
  lfs.chdir(startupdir)
@@ -26117,8 +26115,8 @@
 
 -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
 -- skipped libraries : -
--- original bytes    : 1038245
--- stripped bytes    : 409841
+-- original bytes    : 1038373
+-- stripped bytes    : 409980
 
 -- end library merge
 

Modified: trunk/Master/texmf-dist/scripts/context/stubs/unix/mtxrun
===================================================================
--- trunk/Master/texmf-dist/scripts/context/stubs/unix/mtxrun	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/scripts/context/stubs/unix/mtxrun	2020-03-16 21:11:40 UTC (rev 54364)
@@ -3806,7 +3806,7 @@
 
 package.loaded["l-os"] = package.loaded["l-os"] or true
 
--- original size: 19102, stripped down to: 10192
+-- original size: 19120, stripped down to: 10208
 
 if not modules then modules={} end modules ['l-os']={
  version=1.001,
@@ -4101,7 +4101,7 @@
 end
 local d
 function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ d=d or ((tonumber(date("%H")) or 0)-(tonumber(date("!%H")) or 0))
  if delta then
   if d>0 then
    return format("+%02i:00",d)
@@ -6563,7 +6563,7 @@
 
 package.loaded["util-str"] = package.loaded["util-str"] or true
 
--- original size: 45188, stripped down to: 22734
+-- original size: 45153, stripped down to: 22734
 
 if not modules then modules={} end modules ['util-str']={
  version=1.001,
@@ -10079,7 +10079,7 @@
 
 package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
 
--- original size: 25959, stripped down to: 14893
+-- original size: 26186, stripped down to: 14893
 
 
 local socket=socket or require("socket")
@@ -13961,7 +13961,7 @@
 
 package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
 
--- original size: 9973, stripped down to: 7492
+-- original size: 10184, stripped down to: 7500
 
 if not modules then modules={} end modules ['trac-inf']={
  version=1.001,
@@ -13995,10 +13995,11 @@
 end
 local ticks=clock
 local seconds=function(n) return n or 0 end
-if lua.getpreciseticks then
+if os.type~="windows" then
+elseif lua.getpreciseticks then
  ticks=lua.getpreciseticks
  seconds=lua.getpreciseseconds
-elseif FFISUPPORTED and ffi and os.type=="windows" then
+elseif FFISUPPORTED then
  local okay,kernel=pcall(ffi.load,"kernel32")
  if kernel then
   local tonumber=ffi.number or tonumber
@@ -14136,12 +14137,12 @@
   end)
   if LUATEXENGINE=="luametatex" then
    register("used engine",function()
-    return format("%s version %s, functionality level %s, format id %s",
-     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID)
+    return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID,status.used_compiler)
    end)
   else
    register("used engine",function()
-    return format("%s version %s with functionality level %s, banner: %s",
+    return format("%s version: %s, functionality level: %s, banner: %s",
      LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
    end)
   end
@@ -14149,7 +14150,7 @@
    return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
   end)
   register("callbacks",statistics.callbacks)
-  if TEXENGINE=="luajittex" and JITSUPPORTED then
+  if JITSUPPORTED then
    local jitstatus=jit.status
    if jitstatus then
     local jitstatus={ jitstatus() }
@@ -14183,7 +14184,7 @@
 end
 function statistics.memused() 
  local round=math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB)",
+ return format("%s MB, ctx: %s MB, max: %s MB",
   round(collectgarbage("count")/1000),
   round(status.luastate_bytes/1000000),
   status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
@@ -20789,7 +20790,7 @@
 
 package.loaded["data-ini"] = package.loaded["data-ini"] or true
 
--- original size: 11019, stripped down to: 7086
+-- original size: 10847, stripped down to: 7086
 
 if not modules then modules={} end modules ['data-ini']={
  version=1.001,
@@ -25784,7 +25785,7 @@
 
 package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
 
--- original size: 13964, stripped down to: 10026
+-- original size: 13843, stripped down to: 9991
 
 if not modules then modules={} end modules ['luat-fmt']={
  version=1.001,
@@ -25821,9 +25822,6 @@
  if arguments.errors then
   flags[#flags+1]="--c:errors"
  end
- if arguments.jit then
-  flags[#flags+1]="--c:jiton"
- end
  if arguments.ansi then
   flags[#flags+1]="--c:ansi"
  end
@@ -25991,9 +25989,9 @@
  if silent then
   specification.redirect="> temp.log"
  end
- statistics.starttiming()
+ statistics.starttiming("format")
  local result=runner(specification)
- local runtime=statistics.stoptiming()
+ statistics.stoptiming("format")
  if silent then
   os.remove("temp.log")
  end
@@ -26011,7 +26009,7 @@
  report_format("secondary flags  : %s",secondaryflags)
   end
  report_format("context file     : %s",fulltexsourcename)
- report_format("run time         : %.3f seconds",runtime)
+ report_format("run time         : %.3f seconds",statistics.elapsed("format"))
  report_format("return value     : %s",result==0 and "okay" or "error")
  report_format()
  lfs.chdir(startupdir)
@@ -26117,8 +26115,8 @@
 
 -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
 -- skipped libraries : -
--- original bytes    : 1038245
--- stripped bytes    : 409841
+-- original bytes    : 1038373
+-- stripped bytes    : 409980
 
 -- end library merge
 

Modified: trunk/Master/texmf-dist/scripts/context/stubs/win64/mtxrun.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/context/stubs/win64/mtxrun.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/scripts/context/stubs/win64/mtxrun.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -3806,7 +3806,7 @@
 
 package.loaded["l-os"] = package.loaded["l-os"] or true
 
--- original size: 19102, stripped down to: 10192
+-- original size: 19120, stripped down to: 10208
 
 if not modules then modules={} end modules ['l-os']={
  version=1.001,
@@ -4101,7 +4101,7 @@
 end
 local d
 function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ d=d or ((tonumber(date("%H")) or 0)-(tonumber(date("!%H")) or 0))
  if delta then
   if d>0 then
    return format("+%02i:00",d)
@@ -6563,7 +6563,7 @@
 
 package.loaded["util-str"] = package.loaded["util-str"] or true
 
--- original size: 45188, stripped down to: 22734
+-- original size: 45153, stripped down to: 22734
 
 if not modules then modules={} end modules ['util-str']={
  version=1.001,
@@ -10079,7 +10079,7 @@
 
 package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
 
--- original size: 25959, stripped down to: 14893
+-- original size: 26186, stripped down to: 14893
 
 
 local socket=socket or require("socket")
@@ -13961,7 +13961,7 @@
 
 package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
 
--- original size: 9973, stripped down to: 7492
+-- original size: 10184, stripped down to: 7500
 
 if not modules then modules={} end modules ['trac-inf']={
  version=1.001,
@@ -13995,10 +13995,11 @@
 end
 local ticks=clock
 local seconds=function(n) return n or 0 end
-if lua.getpreciseticks then
+if os.type~="windows" then
+elseif lua.getpreciseticks then
  ticks=lua.getpreciseticks
  seconds=lua.getpreciseseconds
-elseif FFISUPPORTED and ffi and os.type=="windows" then
+elseif FFISUPPORTED then
  local okay,kernel=pcall(ffi.load,"kernel32")
  if kernel then
   local tonumber=ffi.number or tonumber
@@ -14136,12 +14137,12 @@
   end)
   if LUATEXENGINE=="luametatex" then
    register("used engine",function()
-    return format("%s version %s, functionality level %s, format id %s",
-     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID)
+    return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID,status.used_compiler)
    end)
   else
    register("used engine",function()
-    return format("%s version %s with functionality level %s, banner: %s",
+    return format("%s version: %s, functionality level: %s, banner: %s",
      LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
    end)
   end
@@ -14149,7 +14150,7 @@
    return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
   end)
   register("callbacks",statistics.callbacks)
-  if TEXENGINE=="luajittex" and JITSUPPORTED then
+  if JITSUPPORTED then
    local jitstatus=jit.status
    if jitstatus then
     local jitstatus={ jitstatus() }
@@ -14183,7 +14184,7 @@
 end
 function statistics.memused() 
  local round=math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB)",
+ return format("%s MB, ctx: %s MB, max: %s MB",
   round(collectgarbage("count")/1000),
   round(status.luastate_bytes/1000000),
   status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
@@ -20789,7 +20790,7 @@
 
 package.loaded["data-ini"] = package.loaded["data-ini"] or true
 
--- original size: 11019, stripped down to: 7086
+-- original size: 10847, stripped down to: 7086
 
 if not modules then modules={} end modules ['data-ini']={
  version=1.001,
@@ -25784,7 +25785,7 @@
 
 package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
 
--- original size: 13964, stripped down to: 10026
+-- original size: 13843, stripped down to: 9991
 
 if not modules then modules={} end modules ['luat-fmt']={
  version=1.001,
@@ -25821,9 +25822,6 @@
  if arguments.errors then
   flags[#flags+1]="--c:errors"
  end
- if arguments.jit then
-  flags[#flags+1]="--c:jiton"
- end
  if arguments.ansi then
   flags[#flags+1]="--c:ansi"
  end
@@ -25991,9 +25989,9 @@
  if silent then
   specification.redirect="> temp.log"
  end
- statistics.starttiming()
+ statistics.starttiming("format")
  local result=runner(specification)
- local runtime=statistics.stoptiming()
+ statistics.stoptiming("format")
  if silent then
   os.remove("temp.log")
  end
@@ -26011,7 +26009,7 @@
  report_format("secondary flags  : %s",secondaryflags)
   end
  report_format("context file     : %s",fulltexsourcename)
- report_format("run time         : %.3f seconds",runtime)
+ report_format("run time         : %.3f seconds",statistics.elapsed("format"))
  report_format("return value     : %s",result==0 and "okay" or "error")
  report_format()
  lfs.chdir(startupdir)
@@ -26117,8 +26115,8 @@
 
 -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
 -- skipped libraries : -
--- original bytes    : 1038245
--- stripped bytes    : 409841
+-- original bytes    : 1038373
+-- stripped bytes    : 409980
 
 -- end library merge
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkii/cont-new.mkii
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkii/cont-new.mkii	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkii/cont-new.mkii	2020-03-16 21:11:40 UTC (rev 54364)
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2020.02.17 12:06}
+\newcontextversion{2020.03.10 14:44}
 
 %D This file is loaded at runtime, thereby providing an
 %D excellent place for hacks, patches, extensions and new

Modified: trunk/Master/texmf-dist/tex/context/base/mkii/context.mkii
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkii/context.mkii	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkii/context.mkii	2020-03-16 21:11:40 UTC (rev 54364)
@@ -20,7 +20,7 @@
 %D your styles an modules.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2020.02.17 12:06}
+\edef\contextversion{2020.03.10 14:44}
 
 %D For those who want to use this:
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkii/syst-new.mkii
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkii/syst-new.mkii	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkii/syst-new.mkii	2020-03-16 21:11:40 UTC (rev 54364)
@@ -315,6 +315,8 @@
 

 % awaiting the definitive implementation
 
+\let\normalelapsedtime\elapsedtime
+
 \ifx\resettimer\undefined
   \let\resettimer \relax
   \newcount\elapsedtime
@@ -321,11 +323,17 @@
 \fi
 
 \newcount\featuretest
+\newcount\noffeaturetest
+\newcount\featuretesttime
 
-\def\testfeature#1#2%
-  {\def\dotestfeature
-     {\advance\featuretest \plusone
-      \ifnum\featuretest>#1\else#2\expandafter\dotestfeature\fi}%
+\def\testfeature#1#2% brought in sync with mkiv
+  {\noffeaturetest#1\relax
+   \def\dotestfeature
+     {\advance\featuretest\plusone
+      \ifnum\featuretest>\noffeaturetest\else#2\expandafter\dotestfeature\fi}%
+   \def\notestfeature
+     {\advance\featuretest\plusone
+      \ifnum\featuretest>\noffeaturetest\else\expandafter\notestfeature\fi}%
    \retestfeature}
 
 \def\retestfeature % timer support is new per 10/5/2005
@@ -333,13 +341,23 @@
    \ifcase\interactionmode\let\wait\relax\fi
    \writestatus\m!systems{starting feature test}\wait
    \resettimer
+   \bgroup
+   \featuretest\zerocount \notestfeature
+   \global\featuretesttime\normalelapsedtime
+   \egroup
+   \resettimer
+   \bgroup
    \featuretest\zerocount \dotestfeature
-   \writestatus\m!systems{feature test done (\elapsedseconds s)}%
+   \egroup
+   \global\featuretesttime\numexpr\normalelapsedtime-\featuretesttime\relax
+   \writestatus\m!systems{feature test done (used: \elapsedseconds s)}%
    \wait
    \egroup}
 
-\def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\elapsedtime sp\relax}
+\def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\featuretesttime sp\relax}
 
+\let\elapsedtime\elapsedseconds
+
 \def\showtimer#1%
   {\writestatus{runtime}{\elapsedseconds\space s / #1}}
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/attr-col.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/attr-col.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/attr-col.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -259,6 +259,12 @@
     return 0, 0, s
 end
 
+local function hwbtorgb(hue,black,white)
+    local r, g, b = hsvtorgb(hue,1,.5)
+    local f = 1 - white - black
+    return f * r + white, f * g + white , f * b + white
+end
+
 colors.rgbtocmyk  = rgbtocmyk
 colors.rgbtogray  = rgbtogray
 colors.cmyktorgb  = cmyktorgb
@@ -265,6 +271,7 @@
 colors.cmyktogray = cmyktogray
 colors.rgbtohsv   = rgbtohsv
 colors.hsvtorgb   = hsvtorgb
+colors.hwbtorgb   = hwbtorgb
 colors.hsvtogray  = hsvtogray
 colors.graytohsv  = graytohsv
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/attr-ini.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/attr-ini.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/attr-ini.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -160,7 +160,7 @@
 %D performance is better when we put frequently accessed attributes at the front.
 %D So, we might move more here.
 
-\definesystemattribute [state]                                  % nomath
+%definesystemattribute [state]                                  % nomath
 \definesystemattribute [color]               [public]           % global
 \definesystemattribute [colormodel]          [public,global]
 % \definesystemattribute [skip]

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/back-exp.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/back-exp.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/back-exp.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -2178,7 +2178,7 @@
         local n = 0
         for k, v in next, a do
             n = n + 1
-            r[n] = f_attribute(k,v) -- lpegmatch(p_escaped,v)
+            r[n] = f_attribute(k,tostring(v)) -- tostring because of %q
         end
         sort(r)
         return concat(r,"")
@@ -2189,7 +2189,7 @@
         local n = 0
         for k, v in next, a do
             n = n + 1
-            r[n] = f_property(exportproperties,k,v)
+            r[n] = f_property(exportproperties,k,tostring(v)) -- tostring because of %q
         end
         sort(r)
         return concat(r,"")

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/char-utf.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/char-utf.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/char-utf.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -25,7 +25,7 @@
 local next, type = next, type
 local gsub, find = string.gsub, string.find
 local concat, sortedhash, keys, sort = table.concat, table.sortedhash, table.keys, table.sort
-local utfchar, utfbyte, utfcharacters, utfvalues = utf.char, utf.byte, utf.characters, utf.values
+local utfchar, utfbyte, utfcharacters = utf.char, utf.byte, utf.characters
 local P, Cs, Cmt, Ct = lpeg.P, lpeg.Cs, lpeg.Cmt, lpeg.Ct
 
 if not characters        then require("char-def") end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/cldf-bas.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/cldf-bas.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/cldf-bas.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -34,6 +34,8 @@
 local variables     = interfaces.variables
 
 local ctx_flushnode = context.nuts.flush
+local ctx_sprint    = context.sprint
+local txtcatcodes   = tex.txtcatcodes
 
 local nuts          = nodes.nuts
 local tonode        = nuts.tonode
@@ -47,6 +49,8 @@
 local texgetcount   = tex.getcount
 local texsetcount   = tex.setcount
 
+local is_letter     = characters.is_letter
+
 -- a set of basic fast ones
 
 function context.setfontid(n)
@@ -72,6 +76,14 @@
     end
 end
 
+function context.safechar(c)
+    if characters.is_letter[c] then -- not yet loaded
+        ctx_sprint(c)
+    else
+        ctx_sprint(txtcatcodes,c)
+    end
+end
+
 function context.utfchar(k)
     if type(k) == "string" then
         k = tonumber(k)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/colo-ini.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/colo-ini.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/colo-ini.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -449,7 +449,8 @@
             local r = settings.r
             local g = settings.g
             local b = settings.b
-            if r or g or b then
+            local w = settings.w
+            if r or g or (b and not w) then
                 -- we can consider a combined rgb cmyk s definition
                 definecolor(name, register_color(name,'rgb', tonumber(r) or 0, tonumber(g) or 0, tonumber(b) or 0), global)
             else
@@ -467,16 +468,21 @@
                         r, g, b = colors.hsvtorgb(tonumber(h) or 0, tonumber(s) or 1, tonumber(v) or 1) -- maybe later native
                         definecolor(name, register_color(name,'rgb',r,g,b), global)
                     else
-                        local x = settings.x or h
-                        if x then
-                            r, g, b = lpegmatch(hexpattern,x) -- can be inlined
-                            if r and g and b then
-                                definecolor(name, register_color(name,'rgb',r,g,b), global)
+                        if w then
+                            r, g, b = colors.hwbtorgb(tonumber(h) or 0, tonumber(b) or 1, tonumber(w) or 1) -- maybe later native
+                            definecolor(name, register_color(name,'rgb',r,g,b), global)
+                        else
+                            local x = settings.x or h
+                            if x then
+                                r, g, b = lpegmatch(hexpattern,x) -- can be inlined
+                                if r and g and b then
+                                    definecolor(name, register_color(name,'rgb',r,g,b), global)
+                                else
+                                    definecolor(name, register_color(name,'gray',r or 0), global)
+                                end
                             else
-                                definecolor(name, register_color(name,'gray',r or 0), global)
+                                definecolor(name, register_color(name,'gray',tonumber(s) or 0), global)
                             end
-                        else
-                            definecolor(name, register_color(name,'gray',tonumber(s) or 0), global)
                         end
                     end
                 end
@@ -520,7 +526,8 @@
             local r = settings.r
             local g = settings.g
             local b = settings.b
-            if r or g or b then
+            local w = settings.w
+            if r or g or (b and not w) then
                 -- we can consider a combined rgb cmyk s definition
                 register_color(name,'rgb', r or 0, g or 0, b or 0)
             else
@@ -538,16 +545,21 @@
                         r, g, b = colors.hsvtorgb(h or 0, s or 1, v or 1) -- maybe later native
                         register_color(name,'rgb',r,g,b)
                     else
-                        local x = settings.x or h
-                        if x then
-                            r, g, b = lpegmatch(hexpattern,x) -- can be inlined
-                            if r and g and b then
-                                register_color(name,'rgb',r,g,b)
+                        if w then
+                            r, g, b = colors.hwbtorgb((tonumber(h) or 0) / 360, tonumber(b) or 1, tonumber(w) or 1) -- maybe later native
+                            register_color(name,'rgb',r,g,b)
+                        else
+                            local x = settings.x or h
+                            if x then
+                                r, g, b = lpegmatch(hexpattern,x) -- can be inlined
+                                if r and g and b then
+                                    register_color(name,'rgb',r,g,b)
+                                else
+                                    register_color(name,'gray',r or 0)
+                                end
                             else
-                                register_color(name,'gray',r or 0)
+                                register_color(name,'gray',s or 0)
                             end
-                        else
-                            register_color(name,'gray',s or 0)
                         end
                     end
                 end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/cont-new.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/cont-new.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/cont-new.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -13,7 +13,7 @@
 
 % \normalend % uncomment this to get the real base runtime
 
-\newcontextversion{2020.02.17 12:06}
+\newcontextversion{2020.03.10 14:44}
 
 %D This file is loaded at runtime, thereby providing an excellent place for
 %D hacks, patches, extensions and new features.

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -45,7 +45,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2020.02.17 12:06}
+\edef\contextversion{2020.03.10 14:44}
 \edef\contextkind   {beta}
 
 %D Kind of special:
@@ -140,7 +140,7 @@
 %D This needs more checking for clashes:
 %D
 %D \starttyping
-%D \doifelsefileexists{l-macro-imp-codes.lua}{\registerctxluafile{l-macro-imp-codes}{}}{}
+%D \doifelsefileexists{l-macro-imp-codes-luatex.lua}{\registerctxluafile{l-macro-imp-codes-luatex}{}}{}
 %D \stoptyping
 
 \loadmarkfile{supp-dir}

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkxl	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkxl	2020-03-16 21:11:40 UTC (rev 54364)
@@ -29,7 +29,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2020.02.17 12:06}
+\edef\contextversion{2020.03.10 14:44}
 \edef\contextkind   {beta}
 
 %D Kind of special:
@@ -126,7 +126,7 @@
 %D This needs more checking for clashes:
 %D
 %D \starttyping
-%D \doifelsefileexists{l-macro-imp-codes.lua}{\registerctxluafile{l-macro-imp-codes}{}}{}
+%D \doifelsefileexists{l-macro-imp-codes-luametatex.lua}{\registerctxluafile{l-macro-imp-codes-luametatex}{}}{}
 %D \stoptyping
 
 \loadmarkfile{supp-dir}

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/data-ini.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/data-ini.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/data-ini.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -217,12 +217,6 @@
 
 environment.texroot = file.collapsepath(texroot)
 
--- if type(profiler) == "table" and not jit then
---     directives.register("system.profile",function()
---         profiler.start("luatex-profile.log")
---     end)
--- end
-
 -- a forward definition
 
 -- Because we use resolvers.resolve a lot later on, we will implement the basics here and

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/data-tex.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/data-tex.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/data-tex.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -84,6 +84,19 @@
     return lpegmatch(linesplitter,str)
 end
 
+-- not really a bottleneck, but it might become:
+--
+-- local splitlines = string.splitlines or function(str)
+--     return lpegmatch(linesplitter,str)
+-- end
+--
+-- directives.register("system.linesplitmethod",function(v)
+--     linesplitter = linesplitters[tonumber(v) or 1] or linesplitters[1]
+--     splitlines = function(str)
+--         return lpegmatch(linesplitter,str)
+--     end
+-- end)
+
 -----------------------------------------
 
 local wideutfcoding = {

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/driv-shp.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/driv-shp.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/driv-shp.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -87,7 +87,6 @@
 local disc_code               <const> = nodecodes.disc
 local math_code               <const> = nodecodes.math
 local rule_code               <const> = nodecodes.rule
-local marginkern_code         <const> = nodecodes.marginkern
 local whatsit_code            <const> = nodecodes.whatsit
 ----- penalty_code            <const> = nodecodes.penalty
 ----- boundary_code           <const> = nodecodes.boundary
@@ -317,7 +316,8 @@
                 code(font,char,pos_h,pos_v)
             end
         elseif command == "node" then
-            hlist_out(packet[2])
+            local h = packet[2]
+            hlist_out(h,getlist(h))
         elseif command == "image" then
             -- doesn't work because intercepted by engine so we use a different
             -- mechanism (for now)
@@ -364,7 +364,7 @@
 
     local width, height, depth, naturalwidth
     if current then
-        naturalwidth, height, depth, factor = getwhd(current,true)
+        naturalwidth, height, depth, factor = getwhd(current,true) -- also get corrected width
         if factor == 0 then
             width = naturalwidth
         else
@@ -549,12 +549,12 @@
               boxheight,
               boxdepth   = getwhd(this_box)
 
-        local cur_h      = 0
-        local cur_v      = 0
+        local cur_h = 0
+        local cur_v = 0
 
-        if not current then
-            current = getlist(this_box)
-        end
+     -- if not current then
+     --     current = getlist(this_box)
+     -- end
 
         -- we can encounter localpar, boundary and penalty nodes but a special
         -- iterator over content nodes won't save much
@@ -572,7 +572,6 @@
                     pos_v = ref_v - (cur_v - y_offset)
                     -- synced
                 end
-             -- local wd, ht, dp = flush_character(current,font,char,false,true,pos_h,pos_v,pos_r)
                 local wd = flush_character(current,font,char,false,true,pos_h,pos_v,pos_r)
                 cur_h = cur_h + wd
             elseif id == glue_code then
@@ -653,9 +652,9 @@
                                     outer_doing_leaders = doing_leaders
                                     doing_leaders       = true
                                     if getid(leader) == vlist_code then
-                                        vlist_out(leader)
+                                        vlist_out(leader,getlist(leader))
                                     else
-                                        hlist_out(leader)
+                                        hlist_out(leader,getlist(leader))
                                     end
                                     doing_leaders = outer_doing_leaders
                                     cur_h = cur_h + width + lx
@@ -758,7 +757,7 @@
             elseif id == kern_code then
                 local kern, factor = getkern(current,true)
                 if kern ~= 0 then
-                    if factor and factor ~= 0 then
+                    if factor ~= 0 then
                         cur_h = cur_h + (1.0 + factor/1000000.0) * kern
                     else
                         cur_h = cur_h + kern
@@ -866,8 +865,6 @@
                 elseif subtype == openwhatsit_code then
                     flushopenout(current)
                 end
-            elseif id == marginkern_code then
-                cur_h = cur_h + getkern(current)
          -- elseif id == localpar_code and start_of_par(current) then
          --     local pardir = getdirection(current) or lefttoright_code
          --     if pardir == righttoleft_code then
@@ -901,11 +898,10 @@
               boxheight,
               boxdepth   = getwhd(this_box)
 
-        local cur_h      = 0
-        local cur_v      = - boxheight
+        local cur_h    = 0
+        local cur_v    = - boxheight
+        local top_edge = cur_v
 
-        local top_edge   = cur_v
-
         if pos_r == righttoleft_code then
             pos_h = ref_h - cur_h
         else
@@ -914,9 +910,9 @@
         pos_v = ref_v - cur_v
         -- synced
 
-        if not current then
-            current = getlist(this_box)
-        end
+     -- if not current then
+     --     current = getlist(this_box)
+     -- end
 
      -- while current do
      --     local id = getid(current)
@@ -984,9 +980,9 @@
                                     outer_doing_leaders = doing_leaders
                                     doing_leaders = true
                                     if getid(leader) == vlist_code then
-                                        vlist_out(leader)
+                                        vlist_out(leader,getlist(leader))
                                     else
-                                        hlist_out(leader)
+                                        hlist_out(leader,getlist(leader))
                                     end
                                     doing_leaders = outer_doing_leaders
                                     cur_v = cur_v + total + ly
@@ -1272,9 +1268,9 @@
     lastfont = nil -- this forces a sync each page / object
 
     if getid(box) == vlist_code then
-        vlist_out(box)
+        vlist_out(box,getlist(box))
     else
-        hlist_out(box)
+        hlist_out(box,getlist(box))
     end
 
     ::DONE::

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-ctx.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-ctx.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-ctx.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -83,8 +83,7 @@
 
 local getattr             = nuts.getattr
 local setattr             = nuts.setattr
-local getprop             = nuts.getprop
-local setprop             = nuts.setprop
+local getstate            = nuts.getstate
 local setsubtype          = nuts.setsubtype
 
 local texgetdimen         = tex.getdimen
@@ -109,6 +108,7 @@
 local designsizefilename  = fontgoodies.designsizes.filename
 
 local ctx_char            = context.char
+local ctx_safechar        = context.safechar
 local ctx_getvalue        = context.getvalue
 
 local otffeatures         = otf.features
@@ -320,6 +320,7 @@
     parameters.x_height      = 0 -- 5
     parameters.quad          = 0 -- 6
     parameters.extra_space   = 0 -- 7
+    parameters.designsize    = 655360
     --
     constructors.enhanceparameters(parameters) -- official copies for us
     --
@@ -2105,7 +2106,7 @@
 
     implement {
         name      = "tochar",
-        actions   = { tochar, context },
+        actions   = { tochar, ctx_safechar },
         arguments = "string",
     }
 
@@ -2651,7 +2652,6 @@
 
     local a_color         = attributes.private('color')
     local a_colormodel    = attributes.private('colormodel')
-    local a_state         = attributes.private('state')
     local m_color         = attributes.list[a_color] or { }
 
     local glyph_code      = nodes.nodecodes.glyph
@@ -2680,7 +2680,7 @@
             head = tonut(head)
             local model = getattr(head,a_colormodel) or 1
             for glyph in nextchar, head do
-                local a = getprop(glyph,a_state)
+                local a = getstate(glyph)
                 if a then
                     local name = colornames[a]
                     if name then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-hsh.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-hsh.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-hsh.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -9,7 +9,7 @@
 local rawget = rawget
 
 local setmetatableindex = table.setmetatableindex
-local currentfont       = font.current
+local currentfont       = font and font.current -- used in the web service
 local allocate          = utilities.storage.allocate
 
 local fonts         = fonts
@@ -103,7 +103,7 @@
     return k == true and identifiers[currentfont()] or nulldata
 end)
 
-do
+if font then
 
     -- to be used
 
@@ -370,8 +370,12 @@
     end
 end)
 
-function font.getfont(id)
-    return identifiers[id]
+if font then
+
+    function font.getfont(id)
+        return identifiers[id]
+    end
+
 end
 
 -- font.setfont = currentfont -- bah, no native 'setfont' as name

Added: trunk/Master/texmf-dist/tex/context/base/mkiv/font-imp-tweaks.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-imp-tweaks.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-imp-tweaks.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -0,0 +1,25 @@
+if not modules then modules = { } end modules ['font-imp-tweaks'] = {
+    version   = 1.001,
+    comment   = "companion to font-ini.mkiv",
+    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+    copyright = "PRAGMA ADE / ConTeXt Development Team",
+    license   = "see context related readme files"
+}
+
+if not context then return end
+
+local addfeature = fonts.handlers.otf.addfeature
+
+addfeature {
+    name    = "uppercasing",
+    type    = "substitution",
+    prepend = true,
+    data    = characters.uccodes
+}
+
+addfeature {
+    name    = "lowercasing",
+    type    = "substitution",
+    prepend = true,
+    data    = characters.lccodes
+}


Property changes on: trunk/Master/texmf-dist/tex/context/base/mkiv/font-imp-tweaks.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-lib.mkvi
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-lib.mkvi	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-lib.mkvi	2020-03-16 21:11:40 UTC (rev 54364)
@@ -24,8 +24,6 @@
 \registerctxluafile{font-cid}{}         % cid maps
 \registerctxluafile{font-map}{optimize}
 
-% the otf font loader:
-
 % helpers
 
 \registerctxluafile{font-otr}{optimize} % opentype fontloader
@@ -118,6 +116,7 @@
 \registerctxluafile{font-imp-italics}{}
 \registerctxluafile{font-imp-dimensions}{}
 \registerctxluafile{font-imp-spacekerns}{}
+\registerctxluafile{font-imp-tweaks}{}
 
 \doifelsefileexists{font-imp-scripts.lua} {
     \registerctxluafile{font-imp-scripts}{}
@@ -175,6 +174,41 @@
     \setbox\zerocount\hpack{\typethreemacro}%
     \setbox\zerocount\hpack{\raise\dp\zerocount\box\zerocount}%
 }
+\protect \endinput
 
-
-\protect \endinput
+% Some simple test with an upgraded data handling. Because in the
+% end most users will use lmtx we can sacrifice some performance
+% in mkiv unless I decide to ship different ots files. The gain
+% in lmtx is hard to determine but the fact that it runs about
+% as fast as luametatex looks quite ok, given the fact that the
+% backend has a significant performance hit. (We're talking of
+% two changes actually, also the state handling got changed which
+% has a bit more impact on lmtx.)
+%
+% \starttext \start
+%
+% Performance can be better in luatex when I decide to backport
+% but it is somewhat context (font) specific which contradicts
+% the fact that we don't want to add package specific features
+% to the engines (which in the end could hurt the other packages)
+% so that might never happen.
+%
+% latin modern (fastest time):
+%
+% old: luatex 2.979 | luametatex 3.198
+% new: luatex 3.399 | luametatex 3.198
+%
+% % \setupbodyfont[pagella] \smallcaps
+%
+% pagella (fastest time):
+%
+% old: luatex 5.098 | luametatex 5.104
+% new: luatex 6.178 | luametatex 4.975
+%
+% \testfeatureonce{1000}{\samplefile{tufte}\par}
+%
+% \page \elapsedtime \stop \stoptext
+%
+% In then end this upgrade was rejected and the experimental code
+% was thrashed (pending possible future lmtx specific variants of
+% font-*.lua).

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-map.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-map.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-map.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -12,7 +12,7 @@
 local P, R, S, C, Ct, Cc, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.match
 local formatters = string.formatters
 local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
-local rshift = bit32.rshift
+local idiv = number.idiv
 
 local trace_loading = false  trackers.register("fonts.loading", function(v) trace_loading = v end)
 local trace_mapping = false  trackers.register("fonts.mapping", function(v) trace_mapping = v end)
@@ -23,45 +23,24 @@
 
 local force_ligatures = false  directives.register("fonts.mapping.forceligatures",function(v) force_ligatures = v end)
 
-local fonts         = fonts or { }
-local mappings      = fonts.mappings or { }
-fonts.mappings      = mappings
+local fonts    = fonts or { }
+local mappings = fonts.mappings or { }
+fonts.mappings = mappings
 
-local allocate      = utilities.storage.allocate
+local allocate = utilities.storage.allocate
 
---[[ldx--
-<p>Eventually this code will disappear because map files are kind
-of obsolete. Some code may move to runtime or auxiliary modules.</p>
-<p>The name to unciode related code will stay of course.</p>
---ldx]]--
+local hex      = R("AF","af","09")
+local hexfour  = (hex*hex*hex^-2) / function(s) return tonumber(s,16) end
+local hexsix   = (hex*hex*hex^-4) / function(s) return tonumber(s,16) end
+local dec      = (R("09")^1) / tonumber
+local period   = P(".")
+local unicode  = (P("uni") + P("UNI")) * (hexfour * (period + P(-1)) * Cc(false) + Ct(hexfour^1) * Cc(true)) -- base planes
+local ucode    = (P("u")   + P("U")  ) * (hexsix  * (period + P(-1)) * Cc(false) + Ct(hexsix ^1) * Cc(true)) -- extended
+local index    = P("index") * dec * Cc(false)
 
--- local function loadlumtable(filename) -- will move to font goodies
---     local lumname = file.replacesuffix(file.basename(filename),"lum")
---     local lumfile = resolvers.findfile(lumname,"map") or ""
---     if lumfile ~= "" and lfs.isfile(lumfile) then
---         if trace_loading or trace_mapping then
---             report_fonts("loading map table %a",lumfile)
---         end
---         lumunic = dofile(lumfile)
---         return lumunic, lumfile
---     end
--- end
+local parser   = unicode + ucode + index
+local parsers  = { }
 
-local hex     = R("AF","af","09")
------ hexfour = (hex*hex*hex*hex)         / function(s) return tonumber(s,16) end
------ hexsix  = (hex*hex*hex*hex*hex*hex) / function(s) return tonumber(s,16) end
-local hexfour = (hex*hex*hex^-2) / function(s) return tonumber(s,16) end
-local hexsix  = (hex*hex*hex^-4) / function(s) return tonumber(s,16) end
-local dec     = (R("09")^1) / tonumber
-local period  = P(".")
-local unicode = (P("uni") + P("UNI")) * (hexfour * (period + P(-1)) * Cc(false) + Ct(hexfour^1) * Cc(true)) -- base planes
-local ucode   = (P("u")   + P("U")  ) * (hexsix  * (period + P(-1)) * Cc(false) + Ct(hexsix ^1) * Cc(true)) -- extended
-local index   = P("index") * dec * Cc(false)
-
-local parser  = unicode + ucode + index
-
-local parsers = { }
-
 local function makenameparser(str)
     if not str or str == "" then
         return parser
@@ -75,82 +54,24 @@
     end
 end
 
-local f_single = formatters["%04X"]
-local f_double = formatters["%04X%04X"]
+local f_single  = formatters["%04X"]
+local f_double  = formatters["%04X%04X"]
+local s_unknown = "FFFD"
 
--- floor(x/256)  => rshift(x, 8)
--- floor(x/1024) => rshift(x,10)
-
--- 0.684 0.661 0,672 0.650 : cache at lua end (more mem)
--- 0.682 0,672 0.698 0.657 : no cache (moderate mem i.e. lua strings)
--- 0.644 0.647 0.655 0.645 : convert in c (less mem in theory)
-
--- local tounicodes = table.setmetatableindex(function(t,unicode)
---     local s
---     if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
---         s = f_single(unicode)
---     else
---         unicode = unicode - 0x10000
---         s = f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
---     end
---     t[unicode] = s
---     return s
--- end)
---
--- local function tounicode16(unicode,name)
---     local s = tounicodes[unicode]
---     if s then
---         return s
---     else
---         report_fonts("can't convert %a in %a into tounicode",unicode,name)
---     end
--- end
---
--- local function tounicode16sequence(unicodes,name)
---     local t = { }
---     for l=1,#unicodes do
---         local u = unicodes[l]
---         local s = tounicodes[u]
---         if s then
---             t[l] = s
---         else
---             report_fonts ("can't convert %a in %a into tounicode",u,name)
---             return
---         end
---     end
---     return concat(t)
--- end
---
--- local function tounicode(unicode,name)
---     if type(unicode) == "table" then
---         local t = { }
---         for l=1,#unicode do
---             local u = unicode[l]
---             local s = tounicodes[u]
---             if s then
---                 t[l] = s
---             else
---                 report_fonts ("can't convert %a in %a into tounicode",u,name)
---                 return
---             end
---         end
---         return concat(t)
---     else
---         local s = tounicodes[unicode]
---         if s then
---             return s
---         else
---             report_fonts("can't convert %a in %a into tounicode",unicode,name)
---         end
---     end
--- end
-
 local function tounicode16(unicode)
     if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
         return f_single(unicode)
+    elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
+        return s_unknown
+    elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
+        return s_unknown
+    elseif unicode >= 0x100000 and unicode <= 0x10FFFF then
+        return s_unknown
+    elseif unicode >= 0x00D800 and unicode <= 0x00DFFF then
+        return s_unknown
     else
         unicode = unicode - 0x10000
-        return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+        return f_double(idiv(k,0x400)+0xD800,unicode%0x400+0xDC00)
     end
 end
 
@@ -160,132 +81,33 @@
         local u = unicodes[l]
         if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then
             t[l] = f_single(u)
+        elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
+            t[l] = s_unknown
+        elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
+            t[l] = s_unknown
+        elseif unicode >= 0x100000 and unicode <= 0x10FFFF then
+            t[l] = s_unknown
+     -- elseif unicode >= 0x00D800 and unicode <= 0x00DFFF then
+        elseif unicode >= 0x00D7FF and unicode <= 0x00DFFF then
+            t[l] = s_unknown
         else
             u = u - 0x10000
-            t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+            t[l] = f_double(idiv(k,0x400)+0xD800,u%0x400+0xDC00)
         end
     end
     return concat(t)
 end
 
--- local function tounicode(unicode)
---     if type(unicode) == "table" then
---         local t = { }
---         for l=1,#unicode do
---             local u = unicode[l]
---             if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then
---                 t[l] = f_single(u)
---             else
---                 u = u - 0x10000
---                 t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
---             end
---         end
---         return concat(t)
---     else
---         if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
---             return f_single(unicode)
---         else
---             unicode = unicode - 0x10000
---             return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
---         end
---     end
--- end
 
-local unknown = f_single(0xFFFD)
-
--- local function tounicode(unicode)
---     if type(unicode) == "table" then
---         local t = { }
---         for l=1,#unicode do
---             t[l] = tounicode(unicode[l])
---         end
---         return concat(t)
---     elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
---         return unknown
---     elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
---         return unknown
---     elseif unicode >= 0x100000 and unicode <=  0x10FFFF then
---         return unknown
---     elseif unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
---         return f_single(unicode)
---     else
---         unicode = unicode - 0x10000
---         return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
---     end
--- end
-
--- local hash = table.setmetatableindex(function(t,k)
---     local v
---     if k >= 0x00E000 and k <= 0x00F8FF then
---         v = unknown
---     elseif k >= 0x0F0000 and k <= 0x0FFFFF then
---         v = unknown
---     elseif k >= 0x100000 and k <= 0x10FFFF then
---         v = unknown
---     elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
---         v = f_single(k)
---     else
---         local k = k - 0x10000
---         v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
---     end
---     t[k] = v
---     return v
--- end)
---
--- table.makeweak(hash)
---
--- local function tounicode(unicode)
---     if type(unicode) == "table" then
---         local t = { }
---         for l=1,#unicode do
---             t[l] = hash[unicode[l]]
---         end
---         return concat(t)
---     else
---         return hash[unicode]
---     end
--- end
-
 local hash = { }
 local conc = { }
 
--- table.makeweak(hash)
-
--- table.setmetatableindex(hash,function(t,k)
---     if type(k) == "table" then
---         local n = #k
---         for l=1,n do
---             conc[l] = hash[k[l]]
---         end
---         return concat(conc,"",1,n)
---     end
---     local v
---     if k >= 0x00E000 and k <= 0x00F8FF then
---         v = unknown
---     elseif k >= 0x0F0000 and k <= 0x0FFFFF then
---         v = unknown
---     elseif k >= 0x100000 and k <= 0x10FFFF then
---         v = unknown
---     elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
---         v = f_single(k)
---     else
---         local k = k - 0x10000
---         v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
---     end
---     t[k] = v
---     return v
--- end)
---
--- local function tounicode(unicode)
---     return hash[unicode]
--- end
-
 table.setmetatableindex(hash,function(t,k)
     if k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
         v = f_single(k)
     else
         local k = k - 0x10000
-        v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+        v = f_double(idiv(k,0x400)+0xD800,k%0x400+0xDC00)
     end
     t[k] = v
     return v
@@ -299,11 +121,14 @@
         end
         return concat(conc,"",1,n)
     elseif k >= 0x00E000 and k <= 0x00F8FF then
-        return unknown
+        return s_unknown
     elseif k >= 0x0F0000 and k <= 0x0FFFFF then
-        return unknown
+        return s_unknown
     elseif k >= 0x100000 and k <= 0x10FFFF then
-        return unknown
+        return s_unknown
+ -- elseif k >= 0x00D800 and k <= 0x00DFFF then
+    elseif k >= 0x00D7FF and k <= 0x00DFFF then
+        return s_unknown
     else
         return hash[k]
     end
@@ -314,7 +139,6 @@
         return tonumber(str,16)
     else
         local l, r = match(str,"(....)(....)")
-     -- return (tonumber(l,16))*0x400  + tonumber(r,16) - 0xDC00
         return 0x10000 + (tonumber(l,16)-0xD800)*0x400  + tonumber(r,16) - 0xDC00
     end
 end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-ocl.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-ocl.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-ocl.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -49,6 +49,10 @@
 
 else
 
+    -- Actually we don't need a generic branch at all because (according the the
+    -- internet) other macro packages rely on hb for emoji etc and never used this
+    -- feature of the font loader. So maybe I should just remove this from generic.
+
     local tounicode = fonts.mappings.tounicode16
 
     function otf.getactualtext(s)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-ogr.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-ogr.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-ogr.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -83,6 +83,8 @@
         return slot, droppedin, d_tfmdata, d_properties
     end
 
+    -- todo: delay this, in which case we can be leaner and meaner
+
     function dropins.clone(method,tfmdata,shapes,...) -- by index
         if method and shapes then
             local characters   = tfmdata.characters
@@ -456,7 +458,7 @@
                 local idx  = 255
                 local slot = 0
                 --
-                -- todo: delay
+                -- maybe delay in which case we have less fonts as we can be sparse
                 --
                 for k, v in next, characters do
                     local index = v.index

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-osd.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-osd.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-osd.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -113,6 +113,8 @@
 local setchar            = nuts.setchar
 local getprop            = nuts.getprop
 local setprop            = nuts.setprop
+local getstate           = nuts.getstate
+local setstate           = nuts.setstate
 
 local ischar             = nuts.ischar
 
@@ -128,7 +130,6 @@
 
 local fontdata           = fonts.hashes.identifiers
 
-local a_state            = attributes.private('state')
 local a_syllabe          = attributes.private('syllabe')
 
 local dotted_circle      = 0x25CC
@@ -958,7 +959,7 @@
             current = start
         else
             current = getnext(n)
-            setprop(start,a_state,s_rphf)
+            setstate(start,s_rphf)
         end
     end
 
@@ -993,9 +994,9 @@
                         local nextcurrent = copy_node(current)
                         copyinjection(nextcurrent,current) -- KE: necessary? HH: probably not as positioning comes later and we rawget/set
                         setlink(tempcurrent,nextcurrent)
-                        setprop(tempcurrent,a_state,s_blwf)
+                        setstate(tempcurrent,s_blwf)
                         tempcurrent = processcharacters(tempcurrent,font)
-                        setprop(tempcurrent,a_state,unsetvalue)
+                        setstate(tempcurrent,unsetvalue)
                         if getchar(next) == getchar(tempcurrent) then
                             flush_list(tempcurrent)
                             if show_syntax_errors then
@@ -1021,7 +1022,7 @@
         -- find base consonant
         local char = getchar(current)
         if consonant[char] then
-            setprop(current,a_state,s_half)
+            setstate(current,s_half)
             if not firstcons then
                 firstcons = current
             end
@@ -1030,10 +1031,10 @@
                 base = current
             elseif blwfcache[char] then
                 -- consonant has below-base form
-                setprop(current,a_state,s_blwf)
+                setstate(current,s_blwf)
             elseif pstfcache[char] then
                 -- consonant has post-base form
-                setprop(current,a_state,s_pstf)
+                setstate(current,s_pstf)
             else
                 base = current
             end
@@ -1107,15 +1108,15 @@
     while current ~= stop do
         local next = getnext(current)
         if next ~= stop and halant[getchar(next)] and getchar(getnext(next)) == c_zwnj then
-            setprop(current,a_state,unsetvalue)
+            setstate(current,unsetvalue)
         end
         current = next
     end
 
-    if base ~= stop and getprop(base,a_state) then -- a_state can also be init
+    if base ~= stop and getstate(base) then -- state can also be init
         local next = getnext(base)
         if halant[getchar(next)] and not (next ~= stop and getchar(getnext(next)) == c_zwj) then
-            setprop(base,a_state,unsetvalue)
+            setstate(base,unsetvalue)
         end
     end
 
@@ -1261,7 +1262,7 @@
                     end
                     bn = next
                 end
-                if getprop(current,a_state) == s_rphf then
+                if getstate(current,s_rphf) then
                     -- position Reph (Ra + H) after post-base 'matra' (if any) since these
                     -- become marks on the 'matra', not on the base glyph
                     if b ~= current then
@@ -1357,7 +1358,7 @@
         local char = ischar(current,startfont)
         local next = getnext(current)
         if char and getprop(current,a_syllabe) == startattr then
-            if halant[char] then -- a_state can also be init
+            if halant[char] then -- state can also be init
                 if next then
                     local char = ischar(next,startfont)
                     if char and zw_char[char] and getprop(next,a_syllabe) == startattr then
@@ -1373,7 +1374,7 @@
              -- setlink(current,start,next) -- maybe
                 start = startnext
                 break
-         -- elseif consonant[char] and ( not getprop(current,a_state) or getprop(current,a_state) == s_init) then
+         -- elseif consonant[char] and (not getstate(current) or getstate(current,s_init) then
          --     startnext = getnext(start)
          --     head = remove_node(head,start)
          --     if current == head then
@@ -1473,7 +1474,7 @@
             while current do
                 local char = ischar(current,startfont)
                 if char and getprop(current,a_syllabe) == startattr then
-                    if consonant[char] and not getprop(current,a_state) == s_pref then
+                    if consonant[char] and not getstate(current,s_pref) then
                         startnext = getnext(start)
                         head = remove_node(head,start)
                         setlink(current,start)
@@ -1504,7 +1505,7 @@
             while current do
                 local char = ischar(current,startfont)
                 if char and getprop(current,a_syllabe) == startattr then
-                    if getprop(current,a_state) == s_pstf then -- post-base
+                    if getstate(current,s_pstf) then -- post-base
                         startnext = getnext(start)
                         head = remove_node(head,start)
                         setlink(getprev(current),start)
@@ -1547,7 +1548,7 @@
         while current do
             local char = ischar(current,startfont)
             if char and getprop(current,a_syllabe) == startattr then
-                local state = getprop(current,a_state)
+                local state = getstate(current)
                 if before_subscript[rephbase] and (state == s_blwf or state == s_pstf) then
                     c = current
                 elseif after_subscript[rephbase] and (state == s_pstf) then
@@ -1628,7 +1629,7 @@
         local char = ischar(current,startfont)
         local next = getnext(current)
         if char and getprop(current,a_syllabe) == startattr then
-            if halant[char] then -- a_state can also be init
+            if halant[char] then -- state can also be init
                 if next then
                     local char = ischar(next,startfont)
                     if char and zw_char[char] and getprop(next,a_syllabe) == startattr then
@@ -1645,7 +1646,7 @@
                 reordered_pre_base_reordering_consonants[start] = true
                 start = startnext
                 return head, start, true
-         -- elseif consonant[char] and ( not getprop(current,a_state) or getprop(current,a_state) == s_init) then
+         -- elseif consonant[char] and (not getstate(current) or getstate(current,s_init)) then
          --     startnext = getnext(start)
          --     head = remove_node(head,start)
          --     if current == head then
@@ -1668,7 +1669,7 @@
     local current = getprev(start)
     while current and getprop(current,a_syllabe) == startattr do
         local char = ischar(current)
-        if ( not dependent_vowel[char] and not getprop(current,a_state) or getprop(current,a_state) == s_init) then
+        if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then
             startnext = getnext(start)
             head = remove_node(head,start)
             if current == head then
@@ -1764,7 +1765,7 @@
                             if afternext and zw_char[getchar(afternext)] then -- ZWJ and ZWNJ prevent creation of reph
                                 current = afternext -- getnext(next)
                             elseif current == start then
-                                setprop(current,a_state,s_rphf)
+                                setstate(current,s_rphf)
                                 current = next
                             else
                                 current = next
@@ -1784,9 +1785,9 @@
                     if found then -- pre-base: pref	Halant + Consonant
                         local next = getnext(current)
                         if found[getchar(next)] or contextchain(found, next) then
-                            if (not getprop(current,a_state) and not getprop(next,a_state)) then	--KE: a_state can also be init...
-                                setprop(current,a_state,s_pref)
-                                setprop(next,a_state,s_pref)
+                            if (not getstate(current) and not getstate(next)) then	--KE: state can also be init...
+                                setstate(current,s_pref)
+                                setstate(next,s_pref)
                                 current = next
                             end
                         end
@@ -1806,8 +1807,8 @@
                         if found[getchar(next)] or contextchain(found, next) then
                             if next ~= stop and getchar(getnext(next)) == c_zwnj then    -- zwnj prevent creation of half
                                 current = next
-                            elseif (not getprop(current,a_state)) then	--KE: a_state can also be init...
-                                setprop(current,a_state,s_half)
+                            elseif (not getstate(current)) then	--KE: state can also be init...
+                                setstate(current,s_half)
                                 if not halfpos then
                                     halfpos = current
                                 end
@@ -1828,9 +1829,9 @@
                     if found then
                         local next = getnext(current)
                         if found[getchar(next)] or contextchain(found, next) then
-                            if (not getprop(current,a_state) and not getprop(next,a_state)) then	--KE: a_state can also be init...
-                                setprop(current,a_state,s_blwf)
-                                setprop(next,a_state,s_blwf)
+                            if (not getstate(current) and not getstate(next)) then --KE: state can also be init...
+                                setstate(current,s_blwf)
+                                setstate(next,s_blwf)
                                 current = next
                                 subpos  = current
                             end
@@ -1849,9 +1850,9 @@
                     if found then
                         local next = getnext(current)
                         if found[getchar(next)] or contextchain(found, next) then
-                            if (not getprop(current,a_state) and not getprop(next,a_state)) then	--KE: a_state can also be init...
-                                setprop(current,a_state,s_pstf)
-                                setprop(next,a_state,s_pstf)
+                            if (not getstate(current) and not getstate(next)) then -- KE: state can also be init...
+                                setstate(current,s_pstf)
+                                setstate(next,s_pstf)
                                 current = next
                                 postpos = current
                             end
@@ -1865,7 +1866,7 @@
 
     local current, base, firstcons = start, nil, nil
 
-    if getprop(start,a_state) == s_rphf then
+    if getstate(start,s_rphf) then
         -- if syllable starts with Ra + H and script has 'Reph' then exclude Reph from candidates for base consonants
         current = getnext(getnext(start))
     end
@@ -1895,13 +1896,13 @@
                         local tmp = getnext(next)
                         local changestop = next == stop
                         setnext(next)
-                        setprop(current,a_state,s_pref)
+                        setstate(current,s_pref)
                         current = processcharacters(current,font)
-                        setprop(current,a_state,s_blwf)
+                        setstate(current,s_blwf)
                         current = processcharacters(current,font)
-                        setprop(current,a_state,s_pstf)
+                        setstate(current,s_pstf)
                         current = processcharacters(current,font)
-                        setprop(current,a_state,unsetvalue)
+                        setstate(current,unsetvalue)
                         if halant[getchar(current)] then
                             setnext(getnext(current),tmp)
                             if show_syntax_errors then
@@ -1927,7 +1928,7 @@
                         firstcons = current
                     end
                     -- check whether consonant has below-base or post-base form or is pre-base reordering Ra
-                    local a = getprop(current,a_state)
+                    local a = getstate(current)
                     if not (a == s_blwf or a == s_pstf or (a ~= s_rphf and a ~= s_blwf and ra[getchar(current)])) then
                         base = current
                     end
@@ -1941,13 +1942,13 @@
     end
 
     if not base then
-        if getprop(start,a_state) == s_rphf then
-            setprop(start,a_state,unsetvalue)
+        if getstate(start,s_rphf) then
+            setstate(start,unsetvalue)
         end
         return head, stop, nbspaces
     else
-        if getprop(base,a_state) then -- a_state can also be init
-            setprop(base,a_state,unsetvalue)
+        if getstate(base) then -- state can also be init
+            setstate(base,unsetvalue)
         end
         basepos = base
     end
@@ -2004,7 +2005,7 @@
 
                 local ppos = getprev(pos) -- necessary?
                 while ppos and getprop(ppos,a_syllabe) == getprop(pos,a_syllabe) do
-                    if getprop(ppos,a_state) == s_pref then
+                    if getstate(ppos,s_pref) then
                         pos = ppos
                     end
                     ppos = getprev(ppos)
@@ -2086,7 +2087,7 @@
     while current ~= last do
         local char = getchar(current)
         local cn   = getnext(current)
-        if halant[char] and ra[ischar(cn)] and getprop(cn,a_state) ~= s_rphf and getprop(cn,a_state) ~= s_blwf then
+        if halant[char] and ra[ischar(cn)] and (not getstate(cn,s_rphf)) and (not getstate(cn,s_blwf)) then
             if after_main[ischar(cn)] then
                 local prev = getprev(current)
                 local next = getnext(cn)
@@ -2730,8 +2731,8 @@
     while current do
         local char = ischar(current,font)
         if char then
-			if n == 0 and not getprop(current,a_state) then
-				setprop(current,a_state,s_init)
+			if n == 0 and not getstate(current) then
+				setstate(current,s_init)
 			end
 			n = n + 1
 		else
@@ -2820,7 +2821,7 @@
         end
         if not syllableend and show_syntax_errors then
             local char = ischar(current,font)
-            if char and not getprop(current,a_state) then -- a_state can also be init
+            if char and not getstate(current) then -- state can also be init
                 local mark = mark_four[char]
                 if mark then
                     head, current = inject_syntax_error(head,current,char)
@@ -2840,8 +2841,8 @@
     while current do
         local char = ischar(current,font)
         if char then
-			if n == 0 and not getprop(current,a_state) then	-- a_state can also be init
-				setprop(current,a_state,s_init)
+			if n == 0 and not getstate(current) then -- state can also be init
+				setstate(current,s_init)
 			end
 			n = n + 1
 		else

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-ota.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-ota.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-ota.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -27,8 +27,6 @@
 analyzers.initializers    = initializers
 analyzers.methods         = methods
 
-local a_state             = attributes.private('state')
-
 local nuts                = nodes.nuts
 local tonut               = nuts.tonut
 
@@ -60,6 +58,26 @@
 process features right.</p>
 --ldx]]--
 
+local setstate = nuts.setstate
+local getstate = nuts.getstate
+
+if not setstate or not getstate then
+    -- generic (might move to the nod lib)
+    setstate = function(n,v)
+        setprop(n,"state",v)
+    end
+    getstate = function(n,v)
+        local s = getprop(n,"state")
+        if v then
+            return s == v
+        else
+            return s
+        end
+    end
+    nuts.setstate = setstate
+    nuts.getstate = getstate
+end
+
 -- never use these numbers directly
 
 local s_init = 1    local s_rphf =  7
@@ -120,28 +138,28 @@
     current = tonut(current)
     while current do
         local char, id = ischar(current,font)
-        if char and not getprop(current,a_state) then
+        if char and not getstate(current) then
             done = true
             local d = descriptions[char]
             if d then
                 if d.class == "mark" then
                     done = true
-                    setprop(current,a_state,s_mark)
+                    setstate(current,s_mark)
                 elseif useunicodemarks and categories[char] == "mn" then
                     done = true
-                    setprop(current,a_state,s_mark)
+                    setstate(current,s_mark)
                 elseif n == 0 then
                     first, last, n = current, current, 1
-                    setprop(current,a_state,s_init)
+                    setstate(current,s_init)
                 else
                     last, n = current, n+1
-                    setprop(current,a_state,s_medi)
+                    setstate(current,s_medi)
                 end
             else -- finish
                 if first and first == last then
-                    setprop(last,a_state,s_isol)
+                    setstate(last,s_isol)
                 elseif last then
-                    setprop(last,a_state,s_fina)
+                    setstate(last,s_fina)
                 end
                 first, last, n = nil, nil, 0
             end
@@ -148,9 +166,9 @@
         elseif char == false then
             -- other font
             if first and first == last then
-                setprop(last,a_state,s_isol)
+                setstate(last,s_isol)
             elseif last then
-                setprop(last,a_state,s_fina)
+                setstate(last,s_fina)
             end
             first, last, n = nil, nil, 0
             if id == math_code then
@@ -160,13 +178,13 @@
             -- always in the middle .. it doesn't make much sense to assign a property
             -- here ... we might at some point decide to flag the components when present
             -- but even then it's kind of bogus
-            setprop(current,a_state,s_medi)
+            setstate(current,s_medi)
             last = current
         else -- finish
             if first and first == last then
-                setprop(last,a_state,s_isol)
+                setstate(last,s_isol)
             elseif last then
-                setprop(last,a_state,s_fina)
+                setstate(last,s_fina)
             end
             first, last, n = nil, nil, 0
             if id == math_code then
@@ -176,9 +194,9 @@
         current = getnext(current)
     end
     if first and first == last then
-        setprop(last,a_state,s_isol)
+        setstate(last,s_isol)
     elseif last then
-        setprop(last,a_state,s_fina)
+        setstate(last,s_fina)
     end
     return head, done
 end
@@ -308,91 +326,91 @@
     current = tonut(current)
     while current do
         local char, id = ischar(current,font)
-        if char and not getprop(current,a_state) then
+        if char and not getstate(current) then
             done = true
             local classifier = classifiers[char]
             if not classifier then
                 if last then
                     if c_last == s_medi or c_last == s_fina then
-                        setprop(last,a_state,s_fina)
+                        setstate(last,s_fina)
                     else
                         warning(last,"fina")
-                        setprop(last,a_state,s_error)
+                        setstate(last,s_error)
                     end
                     first, last = nil, nil
                 elseif first then
                     if c_first == s_medi or c_first == s_fina then
-                        setprop(first,a_state,s_isol)
+                        setstate(first,s_isol)
                     else
                         warning(first,"isol")
-                        setprop(first,a_state,s_error)
+                        setstate(first,s_error)
                     end
                     first = nil
                 end
             elseif classifier == s_mark then
-                setprop(current,a_state,s_mark)
+                setstate(current,s_mark)
             elseif classifier == s_isol then
                 if last then
                     if c_last == s_medi or c_last == s_fina then
-                        setprop(last,a_state,s_fina)
+                        setstate(last,s_fina)
                     else
                         warning(last,"fina")
-                        setprop(last,a_state,s_error)
+                        setstate(last,s_error)
                     end
                     first, last = nil, nil
                 elseif first then
                     if c_first == s_medi or c_first == s_fina then
-                        setprop(first,a_state,s_isol)
+                        setstate(first,s_isol)
                     else
                         warning(first,"isol")
-                        setprop(first,a_state,s_error)
+                        setstate(first,s_error)
                     end
                     first = nil
                 end
-                setprop(current,a_state,s_isol)
+                setstate(current,s_isol)
             elseif classifier == s_medi then
                 if first then
                     last = current
                     c_last = classifier
-                    setprop(current,a_state,s_medi)
+                    setstate(current,s_medi)
                 else
-                    setprop(current,a_state,s_init)
+                    setstate(current,s_init)
                     first = current
                     c_first = classifier
                 end
             elseif classifier == s_fina then
                 if last then
-                    if getprop(last,a_state) ~= s_init then
-                        setprop(last,a_state,s_medi)
+                    if getstate(last) ~= s_init then
+                        setstate(last,s_medi)
                     end
-                    setprop(current,a_state,s_fina)
+                    setstate(current,s_fina)
                     first, last = nil, nil
                 elseif first then
-                 -- if getprop(first,a_state) ~= s_init then
+                 -- if getstate(first) ~= s_init then
                  --     -- needs checking
-                 --     setprop(first,a_state,s_medi)
+                 --     setstate(first,s_medi)
                  -- end
-                    setprop(current,a_state,s_fina)
+                    setstate(current,s_fina)
                     first = nil
                 else
-                    setprop(current,a_state,s_isol)
+                    setstate(current,s_isol)
                 end
             else -- classifier == s_rest
-                setprop(current,a_state,s_rest)
+                setstate(current,s_rest)
                 if last then
                     if c_last == s_medi or c_last == s_fina then
-                        setprop(last,a_state,s_fina)
+                        setstate(last,s_fina)
                     else
                         warning(last,"fina")
-                        setprop(last,a_state,s_error)
+                        setstate(last,s_error)
                     end
                     first, last = nil, nil
                 elseif first then
                     if c_first == s_medi or c_first == s_fina then
-                        setprop(first,a_state,s_isol)
+                        setstate(first,s_isol)
                     else
                         warning(first,"isol")
-                        setprop(first,a_state,s_error)
+                        setstate(first,s_error)
                     end
                     first = nil
                 end
@@ -400,18 +418,18 @@
         else
             if last then
                 if c_last == s_medi or c_last == s_fina then
-                    setprop(last,a_state,s_fina)
+                    setstate(last,s_fina)
                 else
                     warning(last,"fina")
-                    setprop(last,a_state,s_error)
+                    setstate(last,s_error)
                 end
                 first, last = nil, nil
             elseif first then
                 if c_first == s_medi or c_first == s_fina then
-                    setprop(first,a_state,s_isol)
+                    setstate(first,s_isol)
                 else
                     warning(first,"isol")
-                    setprop(first,a_state,s_error)
+                    setstate(first,s_error)
                 end
                 first = nil
             end
@@ -423,17 +441,17 @@
     end
     if last then
         if c_last == s_medi or c_last == s_fina then
-            setprop(last,a_state,s_fina)
+            setstate(last,s_fina)
         else
             warning(last,"fina")
-            setprop(last,a_state,s_error)
+            setstate(last,s_error)
         end
     elseif first then
         if c_first == s_medi or c_first == s_fina then
-            setprop(first,a_state,s_isol)
+            setstate(first,s_isol)
         else
             warning(first,"isol")
-            setprop(first,a_state,s_error)
+            setstate(first,s_error)
         end
     end
     return head, done

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-ots.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-ots.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-ots.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -114,6 +114,14 @@
 --
 -- Todo: just (0=l2r and 1=r2l) or maybe (r2l = true)
 
+-- Experiments with returning the data with the ischar are positive for lmtx but
+-- have a performance hit on mkiv because there we need to wrap ischardata (pending
+-- extensions to luatex which is unlikely to happen for such an experiment because
+-- we then can't remove it). Actually it might make generic slightly faster. Also,
+-- there are some corner cases where a data check comes before a char fetch and
+-- we're talking of millions of calls there. At some point I might make a version
+-- for lmtx that does it slightly different anyway.
+
 local type, next, tonumber = type, next, tonumber
 local random = math.random
 local formatters = string.formatters
@@ -184,8 +192,7 @@
 local getboth            = nuts.getboth
 local setboth            = nuts.setboth
 local getid              = nuts.getid
-local getprop            = nuts.getprop
-local setprop            = nuts.setprop
+local getstate           = nuts.getstate
 local getsubtype         = nuts.getsubtype
 local setsubtype         = nuts.setsubtype
 local getchar            = nuts.getchar
@@ -194,15 +201,26 @@
 local setdisc            = nuts.setdisc
 local getreplace         = nuts.getreplace
 local setlink            = nuts.setlink
-local getcomponents      = nuts.getcomponents -- the original one, not yet node-aux
-local setcomponents      = nuts.setcomponents -- the original one, not yet node-aux
 local getwidth           = nuts.getwidth
 local getattr            = nuts.getattr
 
 local getglyphdata       = nuts.getglyphdata
 
+---------------------------------------------------------------------------------------
+
+-- Beware: In ConTeXt components no longer are real components. We only keep track of
+-- their positions because some complex ligatures might need that. For the moment we
+-- use an x_ prefix because for now generic follows the other approach.
+
+local copy_no_components = nuts.copy_no_components
+local copy_only_glyphs   = nuts.copy_only_glyphs
+local count_components   = nuts.count_components
+local set_components     = nuts.set_components
+local get_components     = nuts.get_components
+
+---------------------------------------------------------------------------------------
+
 local ischar             = nuts.ischar
-local isglyph            = nuts.isglyph
 local usesfont           = nuts.uses_font
 
 local insert_node_after  = nuts.insert_after
@@ -237,7 +255,6 @@
 local discretionarydisc_code = disccodes.discretionary
 local ligatureglyph_code     = glyphcodes.ligature
 
-local a_state            = attributes.private('state')
 local a_noligature       = attributes.private("noligature")
 
 local injections         = nodes.injections
@@ -450,32 +467,6 @@
     setdisc(disc,pre,post,replace)
 end
 
--- start is a mark and we need to keep that one
-
-local copy_no_components = nuts.copy_no_components
-local copy_only_glyphs   = nuts.copy_only_glyphs
-
-local set_components     = setcomponents
-local take_components    = getcomponents
-
-local function count_components(start,marks)
-    local char = isglyph(start)
-    if char then
-        if getsubtype(start) == ligatureglyph_code then
-            local i = 0
-            local components = getcomponents(start)
-            while components do
-                i = i + count_components(components,marks)
-                components = getnext(components)
-            end
-            return i
-        elseif not marks[char] then
-            return 1
-        end
-    end
-    return 0
-end
-
 local function markstoligature(head,start,stop,char)
     if start == stop and getchar(start) == char then
         return head, start
@@ -531,7 +522,7 @@
     setlink(prev,base,next)
     if not discfound then
         local deletemarks = not skiphash or hasmarks
-        local components = start
+        local components = start -- not used
         local baseindex = 0
         local componentindex = 0
         local head = base
@@ -586,8 +577,9 @@
             -- anyway
             local pre, post, replace, pretail, posttail, replacetail = getdisc(discfound,true)
             if not replace then
+                -- looks like we never come here as it's not okay
                 local prev = getprev(base)
-                local comp = take_components(base)
+             -- local comp = get_components(base) -- already set
                 local copied = copy_only_glyphs(comp)
                 if pre then
                     setlink(discprev,pre)
@@ -594,10 +586,10 @@
                 else
                     setnext(discprev) -- also blocks funny assignments
                 end
-                pre = comp
+                pre = comp -- is start
                 if post then
                     setlink(posttail,discnext)
-                    setprev(post)
+                    setprev(post) -- nil anyway
                 else
                     post = discnext
                     setprev(discnext) -- also blocks funny assignments
@@ -3179,7 +3171,7 @@
     end
     local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
     local renewed = false
-    if (post or replace) then -- and prev then -- hm, we can start with a disc
+    if post or replace then -- and prev then -- hm, we can start with a disc
         if post then
             setlink(posttail,next)
         else
@@ -3287,28 +3279,6 @@
     return getnext(disc), renewed
 end
 
--- We can make some assumptions with respect to discretionaries. First of all it is very
--- unlikely that some of the analysis related attributes applies. Then we can also assume
--- that the ConTeXt specific dynamic attribute is different, although we do use explicit
--- discretionaries (maybe we need to tag those some day). So, at least for now, we don't
--- have the following test in the sub runs:
---
--- -- local a = getglyhpdata(start)
--- -- if a then
--- --     a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
--- -- else
--- --     a = not attribute or getprop(start,a_state) == attribute
--- -- end
--- -- if a then
---
--- but use this instead:
---
--- -- local a = getglyphdata(start)
--- -- if not a or (a == attr) then
---
--- and even that one is probably not needed. However, we can handle interesting
--- cases now:
---
 --  1{2{\oldstyle\discretionary{3}{4}{5}}6}7\par
 --  1{2\discretionary{3{\oldstyle3}}{{\oldstyle4}4}{5{\oldstyle5}5}6}7\par
 
@@ -3420,7 +3390,7 @@
                                         ss = nil
                                     end
                                 end
-lookupmatch = lg
+                                lookupmatch = lg
                             else
                                 break
                             end
@@ -3431,14 +3401,14 @@
                     if l and l.ligature then -- so we test for ligature
                         lastd = d
                     end
--- why not: if not l then break elseif l.ligature then return d end
+                    -- why not: if not l then break elseif l.ligature then return d end
                 else
--- why not: break
+                    -- why not: break
                     -- no match (yet)
                 end
             else
                 -- go on can be a mixed one
--- why not: break
+                -- why not: break
             end
             if lastd then
                 return lastd
@@ -3461,7 +3431,7 @@
             if n == last then
                 break
             end
-            local char = ischar(n)
+            local char = ischar(n,font)
             if char then
                 local lookupmatch = lookupcache[char]
                 if lookupmatch then
@@ -3590,7 +3560,7 @@
                                             ss = nil
                                         end
                                     end
-lookupmatch = lg
+                                    lookupmatch = lg
                                 else
                                     break
                                 end
@@ -3711,26 +3681,6 @@
 
 do
 
-    -- reference:
-    --
-    --  local a = attr and getglyphdata(start)
-    --  if a then
-    --      a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
-    --  else
-    --      a = not attribute or getprop(start,a_state) == attribute
-    --  end
-    --
-    -- used:
-    --
-    --  local a -- happens often so no assignment is faster
-    --  if attr then
-    --      if getglyphdata(start) == attr and (not attribute or getprop(start,a_state) == attribute) then
-    --          a = true
-    --      end
-    --  elseif not attribute or getprop(start,a_state) == attribute then
-    --      a = true
-    --  end
-
     -- This is a measurable experimental speedup (only with hyphenated text and multiple
     -- fonts per processor call), especially for fonts with lots of contextual lookups.
 
@@ -3911,10 +3861,10 @@
                                 if lookupmatch then
                                     local a -- happens often so no assignment is faster
                                     if attr then
-                                        if getglyphdata(start) == attr and (not attribute or getprop(start,a_state) == attribute) then
+                                        if getglyphdata(start) == attr and (not attribute or getstate(start,attribute)) then
                                             a = true
                                         end
-                                    elseif not attribute or getprop(start,a_state) == attribute then
+                                    elseif not attribute or getstate(start,attribute) then
                                         a = true
                                     end
                                     if a then
@@ -3978,10 +3928,10 @@
                                 if m then
                                     local a -- happens often so no assignment is faster
                                     if attr then
-                                        if getglyphdata(start) == attr and (not attribute or getprop(start,a_state) == attribute) then
+                                        if getglyphdata(start) == attr and (not attribute or getstate(start,attribute)) then
                                             a = true
                                         end
-                                    elseif not attribute or getprop(start,a_state) == attribute then
+                                    elseif not attribute or getstate(start,attribute) then
                                         a = true
                                     end
                                     if a then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-oup.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-oup.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-oup.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -1368,65 +1368,6 @@
             end
         end
 
-     -- -- This was an experiment to see if we can bypass the luajit limits but loading is
-     -- -- still an issue due to other limits so we don't use this ... actually it can
-     -- -- prevent a luajittex crash but i don't care too much about that as we can't use
-     -- -- that engine anyway then.
-     --
-     -- local function check(t)
-     --     if type(t) == "table" then
-     --         local s = sortedkeys(t)
-     --         local n = #s
-     --         if n <= 10 then
-     --             return
-     --         end
-     --         local ranges = { }
-     --         local first, last
-     --         for i=1,#s do
-     --             local ti = s[i]
-     --             if not first then
-     --                 first = ti
-     --                 last  = ti
-     --             elseif ti == last + 1 then
-     --                 last = ti
-     --             elseif last - first < 10 then
-     --                 -- we could permits a few exceptions
-     --                 return
-     --             else
-     --                 ranges[#ranges+1] = { first, last }
-     --                 first, last = nil, nil
-     --             end
-     --         end
-     --         if #ranges > 0 then
-     --             return {
-     --                 ranges = ranges
-     --             }
-     --         end
-     --     end
-     -- end
-     --
-     -- local function pack_boolean(v)
-     --     local tag
-     --     local r = check(v)
-     --     if r then
-     --         v = r
-     --         tag = tabstr_normal(v)
-     --     else
-     --         tag = tabstr_boolean(v)
-     --     end
-     --     local ht = h[tag]
-     --     if ht then
-     --         c[ht] = c[ht] + 1
-     --         return ht
-     --     else
-     --         nt = nt + 1
-     --         t[nt] = v
-     --         h[tag] = nt
-     --         c[nt] = 1
-     --         return nt
-     --     end
-     -- end
-
         local function pack_final(v)
             -- v == number
             if c[v] <= criterium then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-pre.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-pre.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-pre.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -855,6 +855,15 @@
 %    \endgroup}
 
 %D \macros
+%D   {uppercasing, lowercasing}
+
+\definefontfeature[lowercasing][lowercasing=yes]
+\definefontfeature[uppercasing][uppercasing=yes]
+
+\unexpanded\def\uppercasing{\addff{uppercasing}}
+\unexpanded\def\lowercasing{\addff{lowercasing}}
+
+%D \macros
 %D   {tinyfont}
 %D
 %D By default we load the Computer Modern Roman fonts (but

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/l-macro-imp-optimize.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/l-macro-imp-optimize.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/l-macro-imp-optimize.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -33,19 +33,6 @@
 
     -- We need to check for 64 usage: 0xFFFFFFFFFFFFFFFF (-1)
 
- -- lua.macros.resolvestring [[
- --     #define band(a,b)      (a & b)
- --     #define bnot(a)        (~a & 0xFFFFFFFF)
- --     #define bor(a,b)       ((a | b) & 0xFFFFFFFF)
- --     #define btest(a,b)     ((a & b) ~= 0)
- --     #define bxor(a,b)      ((a ~ b) & 0xFFFFFFFF)
- --     #define rshift(a,b)    ((a & b) ~= 0)
- --     #define extract(a,b,c) ((a >> b) & ~(-1 << c))
- --     #define extract(a,b)   ((a >> b) & 0x1))
- --     #define lshift(a,b)    ((a << b) & 0xFFFFFFFF)
- --     #define rshift(a,b)    ((a >> b) & 0xFFFFFFFF)
- -- ]]
-
 lua.macros.resolvestring [[
 #define band(a,b)      ((a)&(b))
 #define bnot(a)        (~(a)&0xFFFFFFFF)
@@ -52,7 +39,6 @@
 #define bor(a,b)       (((a)|(b))&0xFFFFFFFF)
 #define btest(a,b)     (((a)&(b))~=0)
 #define bxor(a,b)      (((a)~(b))&0xFFFFFFFF)
-#define rshift(a,b)    (((a)&(b))~=0)
 #define extract(a,b,c) (((a)>>(b))&~(-1<<(c)))
 #define extract(a,b)   (((a)>>(b))&0x1)
 #define extract1(a,b)  ((a >> b) & 0x01)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/l-os.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/l-os.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/l-os.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -459,7 +459,7 @@
 local d
 
 function os.timezone(delta)
-    d = d or tonumber(tonumber(date("%H")-date("!%H")))
+    d = d or ((tonumber(date("%H")) or 0) - (tonumber(date("!%H")) or 0))
     if delta then
         if d > 0 then
             return format("+%02i:00",d)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/lang-ini.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/lang-ini.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/lang-ini.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -22,7 +22,7 @@
 local utfbyte = utf.byte
 local format, gsub, gmatch, find = string.format, string.gsub, string.gmatch, string.find
 local concat, sortedkeys, sortedpairs, keys, insert = table.concat, table.sortedkeys, table.sortedpairs, table.keys, table.insert
-local utfbytes, strip, utfcharacters = string.utfvalues, string.strip, utf.characters
+local utfvalues, strip, utfcharacters = string.utfvalues, string.strip, utf.characters
 
 local context   = context
 local commands  = commands
@@ -194,7 +194,7 @@
                 setcode(utfbyte(l))
             end
         else
-            for l in utfbytes(c) do
+            for l in utfvalues(c) do
                 setcode(l)
             end
         end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/lang-url.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/lang-url.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/lang-url.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -6,7 +6,7 @@
     license   = "see context related readme files"
 }
 
-local utfcharacters, utfvalues, utfbyte, utfchar = utf.characters, utf.values, utf.byte, utf.char
+local utfcharacters, utfbyte, utfchar = utf.characters, utf.byte, utf.char
 local min, max = math.min, math.max
 
 local context   = context

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/lpdf-lmt.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/lpdf-lmt.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/lpdf-lmt.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -102,12 +102,12 @@
 
 local function reset_variables(specification)
     pdf_h, pdf_v  = 0, 0
-    cmrx, cmry    = 1, 1
-    cmsx, cmsy    = 0, 0
-    cmtx, cmty    = 0, 0
-    tmrx, tmry    = 1, 1
-    tmsx, tmsy    = 0, 0
-    tmtx, tmty    = 0, 0
+    cmrx, cmry    = 1.0, 1.0
+    cmsx, cmsy    = 0.0, 0.0
+    cmtx, cmty    = 0.0, 0.0
+    tmrx, tmry    = 1.0, 1.0
+    tmsx, tmsy    = 0.0, 0.0
+    tmtx, tmty    = 0.0, 0.0
     need_tm       = false
     need_tf       = false
     need_width    = 0
@@ -117,17 +117,17 @@
     mode          = "page"
     shippingmode  = specification.shippingmode
     objectnumber  = specification.objectnumber
-    cur_tmrx      = 0
+    cur_tmrx      = 0.0
     f_cur         = 0
     f_pdf_cur     = 0 -- nullfont
     f_pdf         = 0 -- nullfont
     fs_cur        = 0
     fs            = 0
-    tj_delta      = 0
     cur_factor    = 0
     cur_f         = false
     cur_e         = false
-    cw            = 0
+    tj_delta      = 0.0
+    cw            = 0.0
     usedfonts     = setmetatableindex(usefont)
     usedxforms    = { }
     usedximages   = { }
@@ -137,7 +137,7 @@
 
 -- buffer
 
-local buffer = { }
+local buffer = lua.newtable(1024,0) -- { }
 local b      = 0
 
 local function reset_buffer()
@@ -384,7 +384,7 @@
         local f = parameters[font].hfactor
         local v = setmetatableindex(function(t,char)
             local e = d and d[char]
-            local w = 0
+            local w
             if e then
                 w = e.width
                 if w then
@@ -391,10 +391,15 @@
                     w =  w * f
                 end
             end
-            e = c[char]
-            if e then
-                w = e.width or 0
+            if not w then
+                e = c[char]
+                if e then
+                    w = e.width or 0
+                end
             end
+            if not w then
+                w = 0
+            end
             t[char] = w
             return w
         end)
@@ -599,9 +604,7 @@
             begin_charmode()
         end
 
-    --  cw = cw + naturalwidth
-    --  cw = cw + width
-        cw = cw + naturalwidth[char]
+        cw = cw + naturalwidth[char] * tmrx
 
         local index = data.index or char
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/luat-cod.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/luat-cod.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/luat-cod.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -154,7 +154,7 @@
 end
 
 if JITSUPPORTED == nil then
-    JITSUPPORTED = LUATEXENGINE == "luajittex" or jit
+    JITSUPPORTED = LUATEXENGINE == "luajittex" or jit -- "or jit" can go
 end
 
 if INITEXMODE == nil then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/luat-fmt.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/luat-fmt.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/luat-fmt.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -21,9 +21,6 @@
     if arguments.silent then
         flags[#flags+1] = "--interaction=batchmode"
     end
- -- if arguments.jit then
- --     flags[#flags+1] = "--jiton"
- -- end
     return concat(flags," ")
 end
 
@@ -43,9 +40,6 @@
     if arguments.errors then
         flags[#flags+1] = "--c:errors"
     end
-    if arguments.jit then
-        flags[#flags+1] = "--c:jiton"
-    end
     if arguments.ansi then
         flags[#flags+1] = "--c:ansi"
     end
@@ -248,9 +242,9 @@
     if silent then
         specification.redirect = "> temp.log"
     end
-    statistics.starttiming()
+    statistics.starttiming("format")
     local result  = runner(specification)
-    local runtime = statistics.stoptiming()
+    statistics.stoptiming("format")
     if silent then
         os.remove("temp.log")
     end
@@ -269,7 +263,7 @@
     report_format("secondary flags  : %s",secondaryflags)
   end
     report_format("context file     : %s",fulltexsourcename)
-    report_format("run time         : %.3f seconds",runtime)
+    report_format("run time         : %.3f seconds",statistics.elapsed("format"))
     report_format("return value     : %s",result == 0 and "okay" or "error")
     report_format()
     -- last we go back to the home base

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/m-fonts-plugins.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/m-fonts-plugins.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/m-fonts-plugins.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -11,18 +11,19 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-%D See source code for comments. I wrote this a follow up on a presentation by
-%D Kai Eigner, left it for a while, and sort of finalized it the last quarter of
-%D 2016. As I don't use this module, apart from maybe testing something, it is
-%D not guaranteed to work. Also, plugins can interfere with other functionality
-%D in \CONTEXT\ so don't expect too much support. The two modules mentioned
-%D below should work in the generic loader too. It's anyhow an illustration of
-%D how \type {ffi} can work be used in a practical application.
+%D See source code for comments. I wrote this a follow up on a presentation by Kai
+%D Eigner at an NTG meeting, then left it for a while, and sort of finalized it the
+%D last quarter of 2016. As I don't use this module, apart from maybe testing
+%D something, it is not guaranteed to work (but fixing should be a no real problem
+%D as I expect apis to be stable). Plugins liek this can interfere with other
+%D functionality in \CONTEXT\ so don't expect too much support. The two modules
+%D mentioned below should work in the generic loader too. It's anyhow an
+%D illustration of how \type {ffi} be used in a practical application.
 
 % \enabletrackers[resolvers.ffilib]
 
 \registerctxluafile{font-txt}{} % generic text handler
-\registerctxluafile{font-phb}{} % harfbuzz plugin
+\registerctxluafile{font-phb}{} % harfbuzz plugin: binary or library (ffi/optional)
 
 \startluacode
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/math-ini.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/math-ini.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/math-ini.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -1492,7 +1492,7 @@
 \to \everymathematics
 
 \setupmathematics
-  [\s!collapsing=\v!none] % was 3 : mathlist wins over specials
+  [\s!collapsing=1] % so that we at least do primes
 
 %D Math italics (experiment)
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/math-tag.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/math-tag.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/math-tag.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -31,7 +31,7 @@
 local getattr           = nuts.getattr
 local getattrlist       = nuts.getattrlist
 local setattr           = nuts.setattr
-local getcomponents     = nuts.getcomponents -- not really needed
+----- getcomponents     = nuts.getcomponents -- not really needed
 local getwidth          = nuts.getwidth
 
 local getnucleus        = nuts.getnucleus
@@ -346,10 +346,10 @@
                                             runner(getlist(n),depth+1)
                                         elseif id == glyph_code then
                                             -- this should not be needed
-                                            local components = getcomponents(n) -- unlikely set
-                                            if components then
-                                                runner(getcomponent,depth+1)
-                                            end
+                                         -- local components = getcomponents(n) -- unlikely set
+                                         -- if components then
+                                         --     runner(getcomponent,depth+1)
+                                         -- end
                                         elseif id == disc_code then
                                             -- this should not be needed
                                             local pre, post, replace = getdisc(n)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/meta-ini.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/meta-ini.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/meta-ini.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -494,6 +494,8 @@
 %D Currently the inheritance of backgrounds does not work and we might drop it
 %D anyway (too messy)
 
+%D This will be cleaned up in \LMTX: we can delay a lot of this.
+
 \newbox\b_meta_variable_box
 
 \let \currentmpvariableclass          \empty
@@ -593,6 +595,8 @@
         \endgroup\meta_prepare_variable_dimension
       \fi}}
 
+% One of these says we need to enable this!
+
 % \def\meta_prepare_variable_yes
 %   {\expandafter\edef\csname\m_meta_current_variable_template\endcsname
 %      {\clf_prepareMPvariable {\m_meta_current_variable}}}

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/mlib-lmp.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/mlib-lmp.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/mlib-lmp.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -142,7 +142,7 @@
 
     function mp.lmt_svg_include()
         local labelfile = metapost.getparameter { "labelfile" }
-        if labelfile then
+        if labelfile and labelfile ~= "" then
             local labels = table.load(labelfile) -- todo: same path as svg file
             if type(labels) == "table" then
                 for i=1,#labels do
@@ -160,29 +160,36 @@
             end
             return
         end
+        local colorfile = metapost.getparameter { "colormap" }
+        local colormap  = false
+        if colorfile and colorfile ~= "" then
+            colormap = metapost.svgcolorremapper(colorfile)
+        end
         local filename = metapost.getparameter { "filename" }
         if filename and filename ~= "" then
             mpdirect ( metapost.svgtomp {
-                data  = io.loaddata(filename),
-                remap = true,
+                data     = io.loaddata(filename),
+                remap    = true,
+                colormap = colormap,
             } )
-            return
+        else
+            local buffer = metapost.getparameter { "buffer" }
+            if buffer then
+                mpdirect ( metapost.svgtomp {
+                    data     = buffers.getcontent(buffer),
+                 -- remap    = true,
+                    colormap = colormap,
+                } )
+            else
+                local code = metapost.getparameter { "code" }
+                if code then
+                    mpdirect ( metapost.svgtomp {
+                        data     = code,
+                        colormap = colormap,
+                    } )
+                end
+            end
         end
-        local buffer = metapost.getparameter { "buffer" }
-        if buffer then
-            mpdirect ( metapost.svgtomp {
-                data  = buffers.getcontent(buffer),
-             -- remap = true,
-            } )
-            return
-        end
-        local code = metapost.getparameter { "code" }
-        if code then
-            mpdirect ( metapost.svgtomp {
-                data = code,
-            } )
-            return
-        end
     end
 
 end
@@ -213,3 +220,5 @@
     end
 
 end
+
+todecimal = xdecimal and xdecimal.new or tonumber -- bonus

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/mlib-svg.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/mlib-svg.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/mlib-svg.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -390,8 +390,46 @@
 -- local function hexcolor (c) return hexhash [c] end -- directly do hexhash [c]
 -- local function hexcolor3(c) return hexhash3[c] end -- directly do hexhash3[c]
 
-local rgbcomponents, withcolor, thecolor  do
+local colormap  = false
 
+local function prepared(t)
+    if type(t) == "table" then
+        local mapping = t.mapping or { }
+        local mapper  = t.mapper
+        local colormap = setmetatableindex(mapping)
+        if mapper then
+            setmetatableindex(colormap,function(t,k)
+                local v = mapper(k)
+                t[k] = v or k
+                return v
+            end)
+        end
+        return colormap
+    else
+        return false
+    end
+end
+
+local colormaps = setmetatableindex(function(t,k)
+    local v = false
+    if type(k) == "string" then
+        v = prepared(table.load(k)) -- todo: same path as svg file
+    elseif type(k) == "table" then
+        v = prepared(k)
+        k = k.name or k
+    end
+    t[k] = v
+    return v
+end)
+
+function metapost.svgcolorremapper(colormap)
+    return colormaps[colormap]
+end
+
+-- todo: cache colors per image / remapper
+
+local colorcomponents, withcolor, thecolor  do
+
     local svgcolors = {
         aliceblue       = 0xF0F8FF, antiquewhite      = 0xFAEBD7, aqua                  = 0x00FFFF, aquamarine       = 0x7FFFD4,
         azure           = 0xF0FFFF, beige             = 0xF5F5DC, bisque                = 0xFFE4C4, black            = 0x000000,
@@ -433,11 +471,13 @@
     }
 
     local f_rgb      = formatters['withcolor svgcolor(%.3N,%.3N,%.3N)']
+    local f_cmyk     = formatters['withcolor svgcmyk(%.3N,%.3N,%.3N,%.3N)']
     local f_gray     = formatters['withcolor svggray(%.3N)']
     local f_rgba     = formatters['withcolor svgcolor(%.3N,%.3N,%.3N) withtransparency (1,%.3N)']
     local f_graya    = formatters['withcolor svggray(%.3N) withtransparency (1,%.3N)']
     local f_name     = formatters['withcolor "%s"']
     local f_svgcolor = formatters['svgcolor(%.3N,%.3N,%.3N)']
+    local f_svgcmyk  = formatters['svgcmyk(%.3N,%.3N,%.3N,%.3N)']
     local f_svggray  = formatters['svggray(%.3N)']
     local f_svgname  = formatters['"%s"']
 
@@ -455,64 +495,164 @@
         return v
     end)
 
-    local p_fraction  = C(p_number) * C("%")^-1 / function(a,b)
-        a = tonumber(a) return a / (b and 100 or 255)
+    local p_fraction  = C(p_number) * C("%")^-1  / function(a,b) return tonumber(a) / (b and 100 or 255) end
+    local p_angle     = C(p_number) * P("deg")^0 / function(a)   return tonumber(a) end
+    local p_percent   = C(p_number) * P("%")     / function(a)   return tonumber(a) / 100 end
+    local p_absolute  = C(p_number)              / tonumber
+
+    local p_left      = P("(")
+    local p_right     = P(")")
+    local p_a         = P("a")^-1
+    local p_h_a_color = p_left
+                      * p_angle
+                      * p_separator   * p_percent
+                      * p_separator   * p_percent
+                      * p_separator^0 * p_absolute^0
+                      * p_right
+
+	local colors      = attributes.colors
+    local colorvalues = colors.values
+    local colorindex  = attributes.list[attributes.private('color')]
+    local hsvtorgb    = colors.hsvtorgb
+    local hwbtorgb    = colors.hwbtorgb
+    local forcedmodel = colors.forcedmodel
+
+    local p_splitcolor =
+        P("#") * C(p_hexdigit*p_hexdigit)^1 / function(r,g,b)
+            return "rgb",
+                tonumber(r or 0, 16) / 255 or 0,
+                tonumber(g or 0, 16) / 255 or 0,
+                tonumber(b or 0, 16) / 255 or 0
+        end
+        +
+        P("rgb") * p_a
+      * p_left * (p_fraction + p_separator)^-3 * (p_absolute  + p_separator)^0 * p_right / function(r,g,b,a)
+            return "rgb", r or 0, g or 0, b or 0, a or false
+        end
+      + P("cmyk")
+      * p_left * (p_absolute + p_separator)^0  * p_right / function(c,m,y,k)
+            return "cmyk", c or 0, m or 0, y or 0, k or 0
+        end
+      + P("hsl") * p_a
+      * p_h_a_color / function(h,s,l,a)
+            local r, g, b = hsvtorgb(h,s,l,a)
+            return "rgb", r or 0, g or 0, b or 0, a or false
+        end
+      + P("hwb") * p_a
+      * p_h_a_color / function(h,w,b,a)
+            local r, g, b = hwbtorgb(h,w,b)
+            return "rgb", r or 0, g or 0, b or 0, a or false
+        end
+
+    function metapost.svgsplitcolor(color)
+        if type(color) == "string" then
+            local what, s1, s2, s3, s4 = lpegmatch(p_splitcolor,color)
+            if not what then
+                local t = triplets[color]
+                if t then
+                    what, s1, s2, s3 = "rgb", t[1], t[2], t[3]
+                end
+            end
+            return what, s1, s2, s3, s4
+        else
+            return "gray", 0, false
+        end
     end
-    local p_hexcolor  = P("#") * C(p_hexdigit*p_hexdigit)^1 / function(r,g,b)
-        return r and tonumber(r,16)/255 or nil, g and tonumber(g,16)/255 or nil, b and tonumber(b,16)/255 or nil
+
+
+    local function registeredcolor(name)
+        local color = colorindex[name]
+        if color then
+            local v = colorvalues[color]
+            local t = forcedmodel(v[1])
+            if t == 2 then
+                return "gray", v[2]
+            elseif t == 3 then
+                return "rgb", v[3], v[4], v[5]
+            elseif t == 4 then
+                return "cmyk", v[6], v[7], v[8], v[9]
+            else
+                --
+            end
+        end
     end
-    local p_rgbacolor = P("rgb") * (P("a")^-1) * P("(") * (p_fraction  + p_separator)^1 * P(")")
 
-    rgbcomponents = function(color)
-        local h = lpegmatch(p_hexcolor,color)
-        if h then
-            return h
+    -- we can have a fast check for #000000
+
+    local function validcolor(color)
+        if colormap then
+            local c = colormap[color]
+            local t = type(c)
+            if t == "table" then
+                local what = t[1]
+                if what == "rgb" then
+                    return
+                        what,
+                        tonumber(t[2]) or 0,
+                        tonumber(t[3]) or 0,
+                        tonumber(t[4]) or 0,
+                        tonumber(t[4]) or false
+                elseif what == "cmyk" then
+                    return
+                        what,
+                        tonumber(t[2]) or 0,
+                        tonumber(t[3]) or 0,
+                        tonumber(t[4]) or 0,
+                        tonumber(t[5]) or 0
+                elseif what == "gray" then
+                    return
+                        what,
+                        tonumber(t[2]) or 0,
+                        tonumber(t[3]) or false
+                end
+            elseif t == "string" then
+                color = c
+            end
         end
-        local r, g, b, a = lpegmatch(p_rgbacolor,color)
-        if r then
-            return r, g or r, b or r
+        local what, s1, s2, s3, s4 = registeredcolor(color)
+        if what then
+            return what, s1, s2, s3, s4
         end
-        local t = triplets[color]
-        return t[1], t[2], t[3]
+        what, s1, s2, s3, s4 = lpegmatch(p_splitcolor,color)
+        if not what then
+            local t = triplets[color]
+            if t then
+                s1, s3, s3 = t[1], t[2], t[3]
+                what = "rgb"
+            end
+        end
+        return what, s1, s2, s3, s4
+    end
 
+    colorcomponents = function(color)
+        local what, s1, s2, s3, s4 = validcolor(color)
+        return s1, s2, s3, s4 -- so 4 means cmyk
     end
 
     withcolor = function(color)
-        local r, g, b = lpegmatch(p_hexcolor,color)
-        if b and not (r == g and g == b) then
-            return f_rgb(r,g,b)
-        elseif r then
-            return f_gray(r)
-        end
-        local r, g, b, a = lpegmatch(p_rgbacolor,color)
-        if a then
-            if a == 1 then
-                if r == g and g == b then
-                    return f_gray(r)
+        local what, s1, s2, s3, s4 = validcolor(color)
+     -- print(color,what, s1, s2, s3, s4)
+        if what == "rgb" then
+            if s4 then
+                if s1 == s2 and s1 == s3 then
+                    return f_graya(s1,s4)
                 else
-                    return f_rgb(r,g,b)
+                    return f_rgba(s1,s2,s3,s4)
                 end
             else
-                if r == g and g == b then
-                    return f_graya(r,a)
+                if s1 == s2 and s1 == s3 then
+                    return f_gray(s1)
                 else
-                    return f_rgba(r,g,b,a)
+                    return f_rgb(s1,s2,s3)
                 end
             end
-        end
-        if not r then
-            local t = triplets[color]
-            if t then
-                r, g, b = t[1], t[2], t[3]
-            end
-        end
-        if r then
-            if r == g and g == b then
-                return f_gray(r)
-            elseif g and b then
-                return f_rgb(r,g,b)
+        elseif what == "cmyk" then
+            return f_cmyk(s1,s2,s3,s4)
+        elseif what == "gray" then
+            if s2 then
+                return f_graya(s1,s2)
             else
-                return f_gray(r)
+                return f_gray(s1)
             end
         end
         return f_name(color)
@@ -519,24 +659,28 @@
     end
 
     thecolor = function(color)
-        local h = lpegmatch(p_hexcolor,color)
-        if h then
-            return h
-        end
-        local r, g, b, a = lpegmatch(p_rgbacolor,color)
-        if not r then
-            local t = triplets[color]
-            if t then
-                r, g, b = t[1], t[2], t[3]
+        local what, s1, s2, s3, s4 = validcolor(color)
+        if what == "rgb" then
+            if s4 then
+                if s1 == s2 and s1 == s3 then
+                    return f_svggraya(s1,s4)
+                else
+                    return f_svgrgba(s1,s2,s3,s4)
+                end
+            else
+                if s1 == s2 and s1 == s3 then
+                    return f_svggray(s1)
+                else
+                    return f_svgrgb(s1,s2,s3)
+                end
             end
-        end
-        if r then
-            if r == g and g == b then
-                return f_svggray(r)
-            elseif g and b then
-                return f_svgcolor(r,g,b)
+        elseif what == "cmyk" then
+            return f_cmyk(s1,s2,s3,s4)
+        elseif what == "gray" then
+            if s2 then
+                return f_svggraya(s1,s2)
             else
-                return f_svggray(r)
+                return f_svggray(s1)
             end
         end
         return f_svgname(color)
@@ -2517,8 +2661,8 @@
                 --
                 local ecolored = v_fill and v_fill ~= "" or false
                 if ecolored then
-                    -- todo
-                    local r, g, b = rgbcomponents(v_fill)
+                    -- todo cmyk
+                    local r, g, b = colorcomponents(v_fill)
                     if r and g and b then
                         t[#t+1] = f_colored(r,g,b)
                     else
@@ -2677,7 +2821,7 @@
 
         end
 
-        function handlers.svg(c,x,y,w,h,noclip,notransform,normalize,usetextindex)
+        function handlers.svg(c,x,y,w,h,noclip,notransform,normalize)
             local at      = c.at
 
             local wrapupviewport
@@ -2739,7 +2883,6 @@
             if boffset then
                 r = r + 1 result[r] = boffset
             end
-            textindex    = usetextindex and 0 or false
 
             at["transform"] = false
             at["viewBox"]   = false
@@ -2805,6 +2948,7 @@
                 definitions = { }
                 tagstyles   = { }
                 classstyles = { }
+                colormap    = specification.colormap
                 for s in xmlcollected(c,"style") do -- can also be in a def, so let's play safe
                     handlestyle(c)
                 end
@@ -2824,8 +2968,14 @@
                 if trace_result then
                     report("result graphic:\n    %\n    t",result)
                 end
-                mps = concat(result," ")
-                root, result, r, definitions, styles = false, false, false, false, false
+                mps         = concat(result," ")
+                root        = false
+                result      = false
+                r           = false
+                definitions = false
+                tagstyles   = false
+                classstyles = false
+                colormap    = false
             else
                 report("missing svg root element")
             end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/node-aux.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/node-aux.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/node-aux.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -22,6 +22,7 @@
 local vlist_code         = nodecodes.vlist
 local attributelist_code = nodecodes.attributelist -- temporary
 local localpar_code      = nodecodes.localpar
+local ligatureglyph_code = nodes.glyphcodes.ligature
 
 local nuts               = nodes.nuts
 local tonut              = nuts.tonut
@@ -36,7 +37,6 @@
 local getattr            = nuts.getattr
 local getboth            = nuts.getboth
 local getprev            = nuts.getprev
-local getcomponents      = nuts.getcomponents
 local getwidth           = nuts.getwidth
 local setwidth           = nuts.setwidth
 local getboxglue         = nuts.getboxglue
@@ -64,6 +64,7 @@
 local find_tail          = nuts.tail
 local getbox             = nuts.getbox
 local count              = nuts.count
+local isglyph            = nuts.isglyph
 
 local nodepool           = nuts.pool
 local new_glue           = nodepool.glue
@@ -381,89 +382,162 @@
     rehpack(tonut(n),...)
 end
 
--- nodemode helper: the next and prev pointers are untouched
+if CONTEXTLMTXMODE > 0 then
 
-function nuts.copy_no_components(g,copyinjection)
-    local components = getcomponents(g)
-    if components then
-        setcomponents(g)
-        local n = copy_node(g)
-        if copyinjection then
-            copyinjection(n,g)
+    local fastcopy = table.fastcopy
+    local getprop  = nuts.getprop
+    local setprop  = nuts.setprop
+
+    local function set_components(base,list)
+        local t = { }
+        local n = 0
+        while list do
+            local char = isglyph(list)
+            if char then
+                n = n + 1
+                t[n] = char
+            end
+            list = getnext(list)
         end
-        setcomponents(g,components)
-        -- maybe also upgrade the subtype but we don't use it anyway
-        return n
-    else
-        local n = copy_node(g)
-        if copyinjection then
-            copyinjection(n,g)
+        setprop(base,"components",n > 0 and t or false)
+    end
+
+    local function get_components(base)
+        return getprop(base,"components")
+    end
+
+    local function copy_no_components(base)
+        local copy = copy_node(base)
+        setprop(copy,"components",false) -- no metatable lookup!
+        return copy
+    end
+
+    local function copy_only_glyphs(base)
+        local t = getprop(base,"components") -- also metatable
+        if t then
+            return fastcopy(t)
         end
+    end
+
+    local function do_count(t,marks)
+        local n = 0
+        if t then
+            for i=1,#t do
+                local c = t[i]
+                if type(c) == "table" then
+                    n = n + do_count(t,marks)
+                elseif not marks[c] then
+                    n = n + 1
+                else
+                    --marks don't count
+                end
+            end
+        end
         return n
     end
-end
 
-function nuts.copy_only_glyphs(current)
-    local head     = nil
-    local previous = nil
-    for n in nextglyph, current do
-        n = copy_node(n)
-        if head then
-            setlink(previous,n)
-        else
-            head = n
+    -- start is a mark and we need to keep that one
+
+    local done = false
+
+    local function count_components(base,marks)
+        local char = isglyph(base)
+        if char then
+            if getsubtype(base) == ligatureglyph_code then
+                if not done then
+                    logs.report("fonts","!")
+                    logs.report("fonts","! check count_components with mkiv !")
+                    logs.report("fonts","!")
+                    done = true
+                end
+                local t = getprop(base,"components")
+                if t then
+                    return do_count(t,marks)
+                end
+            elseif not marks[char] then
+                return 1
+            end
         end
-        previous = n
+        return 0
     end
-    return head
-end
 
--- node- and basemode helper
+    nuts.set_components     = set_components
+    nuts.get_components     = get_components
+    nuts.copy_only_glyphs   = copy_only_glyphs
+    nuts.copy_no_components = copy_no_components
+    nuts.count_components   = count_components
 
-function nuts.use_components(head,current)
-    local components = getcomponents(current)
-    if not components then
-        return head, current, current
+else
+
+    local get_components = node.direct.getcomponents
+    local set_components = node.direct.setcomponents
+
+    local function copy_no_components(g,copyinjection)
+        local components = get_components(g)
+        if components then
+            set_components(g)
+            local n = copy_node(g)
+            if copyinjection then
+                copyinjection(n,g)
+            end
+            set_components(g,components)
+            -- maybe also upgrade the subtype but we don't use it anyway
+            return n
+        else
+            local n = copy_node(g)
+            if copyinjection then
+                copyinjection(n,g)
+            end
+            return n
+        end
     end
-    local prev, next = getboth(current)
-    local first = current
-    local last  = next
-    while components do
-        local gone = current
-        local tail = find_tail(components)
-        if prev then
-            setlink(prev,components)
+
+    local function copy_only_glyphs(current)
+        local head     = nil
+        local previous = nil
+        for n in nextglyph, current do
+            n = copy_node(n)
+            if head then
+                setlink(previous,n)
+            else
+                head = n
+            end
+            previous = n
         end
-        if next then
-            setlink(tail,next)
-        end
-        if first == current then
-            first = components
-        end
-        if head == current then
-            head = components
-        end
-        current = components
-        setcomponents(gone)
-        flush_node(gone)
-        while true do
-            components = getcomponents(current)
-            if components then
-                next = getnext(current)
-                break -- current is composed
+        return head
+    end
+
+    -- start is a mark and we need to keep that one
+
+    local function count_components(start,marks)
+        local char = isglyph(start)
+        if char then
+            if getsubtype(start) == ligatureglyph_code then
+                local n = 0
+                local components = get_components(start)
+                while components do
+                    n = n + count_components(components,marks)
+                    components = getnext(components)
+                end
+                return n
+            elseif not marks[char] then
+                return 1
             end
-            if next == last then
-                last = current
-                break -- components is false
-            end
-            prev    = current
-            current = next
-            next    = getnext(current)
         end
+        return 0
     end
-    return head, first, last
+
+    nuts.set_components     = set_components
+    nuts.get_components     = get_components
+    nuts.copy_only_glyphs   = copy_only_glyphs
+    nuts.copy_no_components = copy_no_components
+    nuts.count_components   = count_components
+
 end
 
+nuts.setcomponents = function() report_error("unsupported: %a","setcomponents") end
+nuts.getcomponents = function() report_error("unsupported: %a","getcomponents") end
+
 do
 
     local localparcodes = nodes.localparcodes
@@ -543,8 +617,8 @@
 
     nuts.find_node = find_node
 
-    nodes.getnormalizeline = nodes.getnormalizeline or function() return 0 end
-    nodes.setnormalizeline = nodes.setnormalizeline or function()          end
+    nodes.getnormalizeline = node.getnormalizeline or function() return 0 end
+    nodes.setnormalizeline = node.setnormalizeline or function()          end
 
     nuts.getnormalizedline = direct.getnormalizedline or function(h)
         if getid(h) == hlist_code and getsubtype(h) == line_code then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/node-ini.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/node-ini.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/node-ini.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -83,7 +83,7 @@
 local boundarycodes = mark(getsubtypes("boundary"))
 local penaltycodes  = mark(getsubtypes("penalty"))
 local kerncodes     = mark(getsubtypes("kern"))
-local margincodes   = mark(getsubtypes("marginkern"))
+local margincodes   = CONTEXTLMTXMODE == 0 and mark(getsubtypes("marginkern")) or { }
 local mathcodes     = mark(getsubtypes("math"))
 local noadcodes     = mark(getsubtypes("noad"))
 local radicalcodes  = mark(getsubtypes("radical"))
@@ -246,7 +246,7 @@
     [nodecodes.hlist]      = listcodes,
     [nodecodes.kern]       = kerncodes,
     [nodecodes.localpar]   = localparcodes,
-    [nodecodes.marginkern] = margincodes,
+ -- [nodecodes.marginkern] = margincodes,
     [nodecodes.math]       = mathcodes,
     [nodecodes.noad]       = noadcodes,
     [nodecodes.penalty]    = penaltycodes,
@@ -257,6 +257,10 @@
     [nodecodes.whatsit]    = whatcodes,
 }
 
+if CONTEXTLMTXMODE == 0 then
+    nodes.subtypes[nodecodes.marginkern] = margincodes
+end
+
 table.setmetatableindex(nodes.subtypes,function(t,k)
     local v = { }
     t[k] = v

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -347,7 +347,7 @@
 local new_rule                = nodepool.rule
 local new_hlist               = nodepool.hlist
 
-local getnormalizeline        = nuts.getnormalizeline
+local getnormalizeline        = nodes.getnormalizeline
 
 -- helpers --
 
@@ -3120,7 +3120,8 @@
                 elseif id == dir_code then
                     -- no need to deal with directions here (as we only support two)
                 elseif id == marginkern_code then
-                     natural = natural + getwidth(current)
+                    -- not in lmtx
+                    natural = natural + getwidth(current)
                 end
                 current = getnext(current)
             end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/node-nut.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/node-nut.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/node-nut.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -829,6 +829,34 @@
     return p
 end
 
+local getstate = direct.getstate
+local setstate = direct.setstate
+
+if not setstate or not getstate then
+    setstate = function(n,v)
+        local p = propertydata[n]
+        if p then
+            p.state = v
+        else
+            propertydata[n] = { state = v }
+        end
+    end
+    getstate = function(n,v)
+        local p = propertydata[n]
+        if p then
+            if v then
+                return p.state == v
+            else
+                return p.state
+            end
+        else
+            return nil
+        end
+    end
+    nuts.setstate = setstate
+    nuts.getstate = getstate
+end
+
 nuts.isdone = function(n,k)
     local p = propertydata[n]
     if not p then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/node-res.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/node-res.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/node-res.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -176,9 +176,16 @@
     setfield(user_node,"type",usercodes.number)
 end
 
-local left_margin_kern  = register_nut(new_nut(nodecodes.marginkern,0))
-local right_margin_kern = register_nut(new_nut(nodecodes.marginkern,1))
+local left_margin_kern, right_margin_kern
 
+if CONTEXTLMTXMODE > 0 then
+    left_margin_kern  = register_nut(new_nut(kern_code,kerncodes.leftmargincode))
+    right_margin_kern = register_nut(new_nut(kern_code,kerncodes.rightmargincode))
+else
+    left_margin_kern  = register_nut(new_nut(nodecodes.marginkern,0))
+    right_margin_kern = register_nut(new_nut(nodecodes.marginkern,1))
+end
+
 local lineskip          = register_nut(new_nut(glue_code,gluecodes.lineskip))
 local baselineskip      = register_nut(new_nut(glue_code,gluecodes.baselineskip))
 local leftskip          = register_nut(new_nut(glue_code,gluecodes.leftskip))

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/sort-ini.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/sort-ini.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/sort-ini.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -51,7 +51,7 @@
 ]]--
 
 local gsub, find, rep, sub, sort, concat, tohash, format = string.gsub, string.find, string.rep, string.sub, table.sort, table.concat, table.tohash, string.format
-local utfbyte, utfchar, utfcharacters, utfvalues = utf.byte, utf.char, utf.characters, utf.values
+local utfbyte, utfchar, utfcharacters = utf.byte, utf.char, utf.characters
 local next, type, tonumber, rawget, rawset = next, type, tonumber, rawget, rawset
 local P, Cs, R, S, lpegmatch, lpegpatterns = lpeg.P, lpeg.Cs, lpeg.R, lpeg.S, lpeg.match, lpeg.patterns
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/spac-prf.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/spac-prf.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/spac-prf.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -244,6 +244,7 @@
                 dp = 0
                 progress()
             elseif id == marginkern_code then
+                -- not in lmtx
                 wd = getwidth(current)
                 ht = 0
                 dp = 0

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/status-files.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/status-lua.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/symb-ini.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/symb-ini.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/symb-ini.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -11,9 +11,8 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-%D The macros described here used to be part of the \type
-%D {core-con} module. I decided to move them here when
-%D symbolsets saw the light. Let their light shine.
+%D The macros described here used to be part of the \type {core-con} module. I
+%D decided to move them here when symbolsets saw the light. Let their light shine.
 
 \writestatus{loading}{ConTeXt Symbol Libraries / Initialization}
 
@@ -24,19 +23,17 @@
 %D \macros
 %D   {definesymbol, symbol}
 %D
-%D Converting numbers or levels into a character, romannumeral,
-%D symbol or something else, is supported by many \CONTEXT\
-%D commands. Therefore we need a mechanism for linking such
-%D numbers to their counterparts.
+%D Converting numbers or levels into a character, romannumeral, symbol or something
+%D else, is supported by many \CONTEXT\ commands. Therefore we need a mechanism for
+%D linking such numbers to their counterparts.
 %D
-%D First we take care of symbols. These are for instance used
-%D in enumerations and itemizations. We have:
+%D First we take care of symbols. These are for instance used in enumerations and
+%D itemizations. We have:
 %D
 %D \showsetup{definesymbol}
 %D \showsetup{symbol}
 %D
-%D Symbols are simply linked to a tag. Such tags can be numbers
-%D or strings.
+%D Symbols are simply linked to a tag. Such tags can be numbers or strings.
 %D
 %D \starttyping
 %D \definesymbol [1]       [$\bullet$]
@@ -72,8 +69,8 @@
 
 \newtoks\everysymbol
 
-%D We don't use the commandhandler as symbols have their own
-%D subsystem for resolving values.
+%D We don't use the commandhandler as symbols have their own subsystem for resolving
+%D values.
 
 \unexpanded\def\definesymbol
   {\dotripleempty\symb_define}
@@ -100,9 +97,8 @@
 
 \def\symbolset#1{\begincsname\??symbolset#1\endcsname} % no [#1], to be used in commalists etc
 
-%D Since symbols are used frequently in interactive
-%D documents, we speed up this one. Well, that was history,
-%D since now we simplified things a bit, because the low
+%D Since symbols are used frequently in interactive documents, we speed up this one.
+%D Well, that was history, since now we simplified things a bit, because the low
 %D level macros have been sped up every now and then.
 
 % We support both:
@@ -241,8 +237,8 @@
 %D
 %D \showsetup{definefiguresymbol}
 %D
-%D By default, such symbols scale along the current bodyfont
-%D size or running font size (which is better).
+%D By default, such symbols scale along the current bodyfont size or running font
+%D size (which is better).
 
 \def\defaultsymbolfactor{10}
 \def\defaultsymbolheight{1.25ex}
@@ -306,8 +302,8 @@
 %D \macros
 %D   {setupsymbolset,startsymbolset}
 %D
-%D From these macro definitions one can deduce that symbols can
-%D be grouped in symbol sets:
+%D From these macro definitions one can deduce that symbols can be grouped in
+%D symbol sets:
 %D
 %D \starttyping
 %D \startsymbolset [navigation 1]
@@ -388,9 +384,8 @@
 
 \unexpanded\def\usesymbols[#1]{\clf_usesymbols{#1}}
 
-%D As longs as symbols are linked to levels or numbers, we can
-%D also use the conversion mechanism, but in for instance the
-%D itemization macros, we prefer symbols because they can more
-%D easier be (partially) redefined.
+%D As longs as symbols are linked to levels or numbers, we can also use the
+%D conversion mechanism, but in for instance the itemization macros, we prefer
+%D symbols because they can more easier be (partially) redefined.
 
 \protect \endinput

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/syst-ini.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/syst-ini.mkxl	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/syst-ini.mkxl	2020-03-16 21:11:40 UTC (rev 54364)
@@ -133,7 +133,7 @@
 %D anyway because there are differences (no backend, to mention one).
 
 \directlua {
-    local primitives = tex.extraprimitives()  % "core","tex","etex","luatex"
+    local primitives = tex.extraprimitives()  % "tex","etex","luatex"
     tex.enableprimitives("normal",primitives) % could default to everything
     function tex.enableprimitives() end       % so we kind of protect what's there
 }
@@ -1108,4 +1108,9 @@
 
 \def\wildcardsymbol{*}
 
+%D For a while we will keep these useless numbers as for instance tikz checks for them:
+
+\chardef\eTeXversion   2
+\def    \eTeXrevision {2}
+
 \protect \endinput

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/tabl-tbl.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/tabl-tbl.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/tabl-tbl.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -1109,8 +1109,8 @@
      \let\tabl_tabulate_insert_head\empty
    \fi
    \ifcsname\??tabulatefoot\currenttabulation\endcsname
-     \expandafter\ifx\csname\??tabulatefoot\currenttabulation\endcsname\empty
-    %\expandafter\ifx\lastnamedcs\empty
+    %\expandafter\ifx\csname\??tabulatefoot\currenttabulation\endcsname\empty
+     \expandafter\ifx\lastnamedcs\empty
        \let\tabl_tabulate_insert_foot\empty
      \else
        \let\tabl_tabulate_insert_foot\tabl_tabulate_insert_foot_content

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/trac-inf.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/trac-inf.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/trac-inf.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -45,13 +45,20 @@
 local ticks   = clock
 local seconds = function(n) return n or 0 end
 
-if lua.getpreciseticks then
+if os.type ~= "windows" then
 
+    -- doesn't work well yet on unix (system time vs process time so a mtxrun
+    -- timing with nested call gives the wrong result)
+
+elseif lua.getpreciseticks then
+
     ticks   = lua.getpreciseticks
     seconds = lua.getpreciseseconds
 
-elseif FFISUPPORTED and ffi and os.type == "windows" then
+elseif FFISUPPORTED then
 
+    -- Do we really care when not in luametatex? For now we do, so:
+
     local okay, kernel = pcall(ffi.load,"kernel32")
 
     if kernel then
@@ -221,12 +228,12 @@
      -- end)
         if LUATEXENGINE == "luametatex" then
             register("used engine", function()
-                return format("%s version %s, functionality level %s, format id %s",
-                    LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, LUATEXFORMATID)
+                return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+                    LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, LUATEXFORMATID, status.used_compiler)
             end)
         else
             register("used engine", function()
-                return format("%s version %s with functionality level %s, banner: %s",
+                return format("%s version: %s, functionality level: %s, banner: %s",
                     LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, lower(status.banner))
             end)
         end
@@ -234,7 +241,7 @@
             return format("%s of %s + %s", status.cs_count, status.hash_size,status.hash_extra)
         end)
         register("callbacks", statistics.callbacks)
-        if TEXENGINE == "luajittex" and JITSUPPORTED then
+        if JITSUPPORTED then
             local jitstatus = jit.status
             if jitstatus then
                 local jitstatus = { jitstatus() }
@@ -272,7 +279,7 @@
 
 function statistics.memused() -- no math.round yet -)
     local round = math.round or math.floor
-    return format("%s MB, ctx: %s MB, max: %s MB)",
+    return format("%s MB, ctx: %s MB, max: %s MB",
         round(collectgarbage("count")/1000),
         round(status.luastate_bytes/1000000),
         status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -142,34 +142,34 @@
 local report_visualize = logs.reporter("visualize")
 
 local modes = {
-    hbox          =      1,
-    vbox          =      2,
-    vtop          =      4,
-    kern          =      8,
-    glue          =     16,
- -- skip          =     16,
-    penalty       =     32,
-    fontkern      =     64,
-    strut         =    128,
-    whatsit       =    256,
-    glyph         =    512,
-    simple        =   1024,
-    simplehbox    =   1024 + 1,
-    simplevbox    =   1024 + 2,
-    simplevtop    =   1024 + 4,
-    user          =   2048,
-    math          =   4096,
-    italic        =   8192,
-    origin        =  16384,
-    discretionary =  32768,
-    expansion     =  65536,
-    line          = 131072,
-    space         = 262144,
-    depth         = 524288,
+    hbox          = 0x000001,
+    vbox          = 0x000002,
+    vtop          = 0x000004,
+    kern          = 0x000008,
+    glue          = 0x000010,
+    penalty       = 0x000020,
+    fontkern      = 0x000040,
+    strut         = 0x000080,
+    whatsit       = 0x000100,
+    glyph         = 0x000200,
+    simple        = 0x000400,
+    simplehbox    = 0x000401,
+    simplevbox    = 0x000402,
+    simplevtop    = 0x000404,
+    user          = 0x000800,
+    math          = 0x001000,
+    italic        = 0x002000,
+    origin        = 0x004000,
+    discretionary = 0x008000,
+    expansion     = 0x010000,
+    line          = 0x020000,
+    space         = 0x040000,
+    depth         = 0x080000,
+    marginkern    = 0x100000,
 }
 
 local usedfont, exheight, emwidth
-local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_italic, l_origin, l_discretionary, l_expansion, l_line, l_space, l_depth
+local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_marginkern, l_italic, l_origin, l_discretionary, l_expansion, l_line, l_space, l_depth
 
 local enabled = false
 local layers  = { }
@@ -178,7 +178,7 @@
 local preset_makeup = preset_boxes
                     + modes.kern + modes.glue + modes.penalty
 local preset_all    = preset_makeup
-                    + modes.fontkern + modes.whatsit + modes.glyph + modes.user + modes.math
+                    + modes.fontkern + modes.marginkern + modes.whatsit + modes.glyph + modes.user + modes.math
 
 function visualizers.setfont(id)
     usedfont = id or current_font()
@@ -222,6 +222,7 @@
     l_user          = layers.user
     l_math          = layers.math
     l_italic        = layers.italic
+    l_marginkern    = layers.marginkern
     l_origin        = layers.origin
     l_discretionary = layers.discretionary
     l_expansion     = layers.expansion
@@ -462,10 +463,11 @@
 
 local caches = setmetatableindex("table")
 
-local fontkern, italickern do
+local fontkern, italickern, marginkern do
 
     local f_cache = caches["fontkern"]
     local i_cache = caches["italickern"]
+    local m_cache = caches["marginkern"]
 
     local function somekern(head,current,cache,color,layer)
         local width = getkern(current)
@@ -503,6 +505,10 @@
         return somekern(head,current,i_cache,c_glyph_d,l_italic)
     end
 
+    marginkern = function(head,current)
+        return somekern(head,current,m_cache,c_glyph_d,l_marginkern)
+    end
+
 end
 
 local glyphexpansion do
@@ -1053,6 +1059,31 @@
 
 end
 
+local ruledmarginkern do
+
+    local m_cache = caches["marginkern"]
+
+    ruledmarginkern = function(head,current)
+        local kern = getkern(current)
+        local info = m_cache[kern]
+        if not info then
+            local amount = formatters["%s:%0.3f"]("MK",kern*pt_factor)
+            if kern > 0 then
+                info = sometext(amount,l_marginkern,c_positive)
+            elseif kern < 0 then
+                info = sometext(amount,l_marginkern,c_negative)
+            else
+                info = sometext(amount,l_marginkern,c_zero)
+            end
+            m_cache[kern] = info
+        end
+        info = copy_list(info)
+        head, current = insert_node_before(head,current,info)
+        return head, getnext(current)
+    end
+
+end
+
 local ruleddiscretionary do
 
     local d_cache = caches["discretionary"]
@@ -1122,10 +1153,12 @@
     local vlist_code      = nodecodes.vlist
     local marginkern_code = nodecodes.marginkern
 
-    local kerncodes       = nodes.kerncodes
-    local fontkern_code   = kerncodes.fontkern
-    local italickern_code = kerncodes.italiccorrection
-    ----- userkern_code   = kerncodes.userkern
+    local kerncodes            = nodes.kerncodes
+    local fontkern_code        = kerncodes.fontkern
+    local italickern_code      = kerncodes.italiccorrection
+    local leftmarginkern_code  = kerncodes.leftmarginkern
+    local rightmarginkern_code = kerncodes.rightmarginkern
+    ----- userkern_code        = kerncodes.userkern
 
     local listcodes       = nodes.listcodes
     local linelist_code   = listcodes.line
@@ -1133,32 +1166,33 @@
     local cache
 
     local function visualize(head,vertical,forced,parent)
-        local trace_hbox           = false
-        local trace_vbox           = false
-        local trace_vtop           = false
-        local trace_kern           = false
-        local trace_glue           = false
-        local trace_penalty        = false
-        local trace_fontkern       = false
-        local trace_strut          = false
-        local trace_whatsit        = false
-        local trace_glyph          = false
-        local trace_simple         = false
-        local trace_user           = false
-        local trace_math           = false
-        local trace_italic         = false
-        local trace_origin         = false
-        local trace_discretionary  = false
-        local trace_expansion      = false
-        local trace_line           = false
-        local trace_space          = false
-        local trace_depth          = false
-        local current              = head
-        local previous             = nil
-        local attr                 = unsetvalue
-        local prev_trace_fontkern  = nil
-        local prev_trace_italic    = nil
-        local prev_trace_expansion = nil
+        local trace_hbox            = false
+        local trace_vbox            = false
+        local trace_vtop            = false
+        local trace_kern            = false
+        local trace_glue            = false
+        local trace_penalty         = false
+        local trace_fontkern        = false
+        local trace_strut           = false
+        local trace_whatsit         = false
+        local trace_glyph           = false
+        local trace_simple          = false
+        local trace_user            = false
+        local trace_math            = false
+        local trace_italic          = false
+        local trace_origin          = false
+        local trace_discretionary   = false
+        local trace_expansion       = false
+        local trace_line            = false
+        local trace_space           = false
+        local trace_depth           = false
+        local current               = head
+        local previous              = nil
+        local attr                  = unsetvalue
+        local prev_trace_fontkern   = nil
+        local prev_trace_marginkern = nil
+        local prev_trace_italic     = nil
+        local prev_trace_expansion  = nil
 
      -- local function setthem(t,k)
      --     local v_trace_hbox          = band(k,     1) ~= 0
@@ -1215,9 +1249,10 @@
             local id = getid(current)
             local a = forced or getattr(current,a_visual) or unsetvalue
             if a ~= attr then
-                prev_trace_fontkern  = trace_fontkern
-                prev_trace_italic    = trace_italic
-                prev_trace_expansion = trace_expansion
+                prev_trace_fontkern   = trace_fontkern
+                prev_trace_italic     = trace_italic
+                prev_trace_marginkern = trace_marginkern
+                prev_trace_expansion  = trace_expansion
                 attr = a
                 if a == unsetvalue then
                     trace_hbox          = false
@@ -1240,29 +1275,31 @@
                     trace_line          = false
                     trace_space         = false
                     trace_depth         = false
+                    trace_marginkern    = false
                     goto list
                 else -- dead slow:
                  -- cache[a]()
-                    trace_hbox          = band(a,     1) ~= 0
-                    trace_vbox          = band(a,     2) ~= 0
-                    trace_vtop          = band(a,     4) ~= 0
-                    trace_kern          = band(a,     8) ~= 0
-                    trace_glue          = band(a,    16) ~= 0
-                    trace_penalty       = band(a,    32) ~= 0
-                    trace_fontkern      = band(a,    64) ~= 0
-                    trace_strut         = band(a,   128) ~= 0
-                    trace_whatsit       = band(a,   256) ~= 0
-                    trace_glyph         = band(a,   512) ~= 0
-                    trace_simple        = band(a,  1024) ~= 0
-                    trace_user          = band(a,  2048) ~= 0
-                    trace_math          = band(a,  4096) ~= 0
-                    trace_italic        = band(a,  8192) ~= 0
-                    trace_origin        = band(a, 16384) ~= 0
-                    trace_discretionary = band(a, 32768) ~= 0
-                    trace_expansion     = band(a, 65536) ~= 0
-                    trace_line          = band(a,131072) ~= 0
-                    trace_space         = band(a,262144) ~= 0
-                    trace_depth         = band(a,524288) ~= 0
+                    trace_hbox          = band(a,0x000001) ~= 0
+                    trace_vbox          = band(a,0x000002) ~= 0
+                    trace_vtop          = band(a,0x000004) ~= 0
+                    trace_kern          = band(a,0x000008) ~= 0
+                    trace_glue          = band(a,0x000010) ~= 0
+                    trace_penalty       = band(a,0x000020) ~= 0
+                    trace_fontkern      = band(a,0x000040) ~= 0
+                    trace_strut         = band(a,0x000080) ~= 0
+                    trace_whatsit       = band(a,0x000100) ~= 0
+                    trace_glyph         = band(a,0x000200) ~= 0
+                    trace_simple        = band(a,0x000400) ~= 0
+                    trace_user          = band(a,0x000800) ~= 0
+                    trace_math          = band(a,0x001000) ~= 0
+                    trace_italic        = band(a,0x002000) ~= 0
+                    trace_origin        = band(a,0x004000) ~= 0
+                    trace_discretionary = band(a,0x008000) ~= 0
+                    trace_expansion     = band(a,0x010000) ~= 0
+                    trace_line          = band(a,0x020000) ~= 0
+                    trace_space         = band(a,0x040000) ~= 0
+                    trace_depth         = band(a,0x080000) ~= 0
+                    trace_marginkern    = band(a,0x100000) ~= 0
                 end
             elseif a == unsetvalue then
                 goto list
@@ -1306,6 +1343,12 @@
                     elseif trace_kern then
                         head, current = ruleditalic(head,current)
                     end
+                elseif subtype == leftmarginkern_code or subtype == rightmarginkern_code then
+                    if trace_marginkern or prev_trace_marginkern then
+                        head, current = marginkern(head,current)
+                    elseif trace_kern then
+                        head, current = ruledmarginkern(head,current)
+                    end
                 else
                     if trace_kern then
                         head, current = ruledkern(head,current,vertical)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/typo-brk.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/typo-brk.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/typo-brk.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -59,11 +59,12 @@
    \endgroup}
 
 \unexpanded\def\setbreakpoints[#1]%
-  {\exhyphenchar\minusone % we use a different order tha   n base tex, so we really need this
+  {\exhyphenchar\minusone % we use a different order than base tex, so we really need this
    \clf_setbreakpoints{#1}}
 
 \unexpanded\def\resetbreakpoints
-  {\attribute\breakpointattribute\attributeunsetvalue}
+  {\exhyphenchar\hyphenasciicode % 2020.03.05
+   \attribute\breakpointattribute\attributeunsetvalue}
 
 \definebreakpoints[compound]
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/typo-cap.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/typo-cap.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/typo-cap.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -40,7 +40,6 @@
 \definecapitals[\v!capital]         % one upper + font
 \definecapitals[\v!Capital]         % some upper + font
 \definecapitals[\v!mixed]           % UpperCase
-\definecapitals[\v!WORD]            % all lower
 \definecapitals[\v!Word]            % one upper + font
 \definecapitals[\v!Words]           % some upper
 \definecapitals[\v!camel]           % lowers first

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/typo-dha.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/typo-dha.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/typo-dha.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -59,6 +59,7 @@
 local isglyph            = nuts.isglyph -- or ischar
 
 local setprop            = nuts.setprop
+local setstate           = nuts.setstate
 local setchar            = nuts.setchar
 
 local insert_node_before = nuts.insert_before
@@ -100,7 +101,6 @@
 local setcolor           = directions.setcolor
 local getglobal          = directions.getglobal
 
-local a_state            = attributes.private('state')
 local a_directions       = attributes.private('directions')
 
 local strip              = false
@@ -191,7 +191,7 @@
                             end
                         elseif lro or override < 0 then
                             if direction == "r" or direction == "al" then
-                                setprop(current,a_state,s_isol) -- hm
+                                setstate(current,s_isol) -- hm
                                 direction = "l"
                                 reversed  = true
                             end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -180,6 +180,8 @@
          --        nodes.handlers.protectglyphs(temp)  -- not needed as we discard
          -- temp = typesetters.spacings.handler(temp)  -- maybe when enabled
          -- temp = typesetters.kerns.handler(temp)     -- maybe when enabled
+-- temp = typesetters.cases.handler(temp)     -- maybe when enabled
+flush_node_list(temp);
             local width = getdimensions(temp)
             return width
         end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/typo-itc.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/typo-itc.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/typo-itc.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -45,7 +45,7 @@
 local getheight           = nuts.getheight
 
 local insert_node_after   = nuts.insert_after
-local delete_node         = nuts.delete
+local remove_node         = nuts.remove
 local end_of_math         = nuts.end_of_math
 
 local texgetattribute     = tex.getattribute
@@ -315,7 +315,7 @@
                     if trace_italics then
                         report_italics("deleting last correction before %s %C",char,"glyph")
                     end
-                    delete_node(prevhead,previnserted)
+                    remove_node(prevhead,previnserted,true)
                 else
                     --
                     if replaceitalic ~= 0 then
@@ -327,7 +327,7 @@
                         if trace_italics then
                             report_italics("deleting last correction before %s %C","replace",char)
                         end
-                        delete_node(replacehead,replaceinserted)
+                        remove_node(replacehead,replaceinserted,true)
                     end
                     --
                     if postitalic ~= 0 then
@@ -339,7 +339,7 @@
                         if trace_italics then
                             report_italics("deleting last correction before %s %C","post",char)
                         end
-                        delete_node(posthead,postinserted)
+                        remove_node(posthead,postinserted,true)
                     end
                 end
                 --

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -28,7 +28,6 @@
 local insert_node_before = nuts.insert_before
 local insert_node_after  = nuts.insert_after
 local end_of_math        = nuts.end_of_math
-local use_components     = nuts.use_components
 local copy_node          = nuts.copy
 
 local getnext            = nuts.getnext
@@ -365,209 +364,6 @@
     end
 end
 
--- function kerns.handler(head)
---     local start        = head
---     local lastfont     = nil
---     local keepligature = kerns.keepligature
---     local keeptogether = kerns.keeptogether
---     local fillup       = false
---     local bound        = false
---     local prev         = nil
---     local previd       = nil
---     local prevchar     = nil
---     local prevfont     = nil
---     local prevmark     = nil
---     while start do
---         -- fontkerns don't get the attribute but they always sit between glyphs so
---         -- are always valid bound .. disc nodes also somtimes don't get them
---         local id   = getid(start)
---         local attr = takeattr(start,a_kerns)
---         if attr and attr > 0 then
---             local krn = mapping[attr]
---             if krn == v_max then
---                 krn    = .25
---                 fillup = true
---             else
---                 fillup = false
---             end
---             if not krn or krn == 0 then
---                 bound = false
---             elseif id == glyph_code then
---                 if keepligature and keepligature(start) then
---                     -- keep 'm
---                 else
---                     -- we could use the subtype ligature but that's also a call
---                     -- todo: check tounicode and use that information to split
---                     head, start = use_components(head,start)
---                 end
---                 local char, font = isglyph(start)
---                 local mark = markdata[font]
---                 if not bound then
---                     -- yet
---                 elseif mark[char] then
---                     -- skip
---                 elseif previd == kern_code then
---                     if getsubtype(prev) == fontkern_code then
---                         local inject = true
---                         if keeptogether then
---                             if previd == glyph_code and keeptogether(prev,start) then
---                                 inject = false
---                             end
---                         end
---                         if inject then
---                             -- not yet ok, as injected kerns can be overlays (from node-inj.lua)
---                             setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code)
---                         end
---                     end
---                 elseif previd == glyph_code then
---                     if prevfont == font then
---                         if keeptogether and keeptogether(prev,start) then
---                             -- keep 'm
---                         else
---                             local data  = chardata[font][prevchar]
---                             local kerns = data and data.kerns
---                             local kern  = (kerns and kerns[char] or 0) + quaddata[font]*krn
---                             insert_node_before(head,start,kern_injector(fillup,kern))
---                         end
---                     else
---                         insert_node_before(head,start,kern_injector(fillup,quaddata[font]*krn))
---                     end
---                 end
---                 prev     = start
---                 prevchar = char
---                 prevfont = font
---                 prevmark = mark
---                 previd   = id
---                 bound    = true
---             elseif id == disc_code then
---                 local prev, next, pglyph, nglyph -- delayed till needed
---                 local subtype = getsubtype(start)
---              -- if subtype == automaticdisc_code then
---              --     -- this is kind of special, as we have already injected the
---              --     -- previous kern
---              --     local prev   = getprev(start)
---              --     local pglyph = prev and getid(prev) == glyph_code
---              --     languages.expand(start,pglyph and prev)
---              --     -- we can have a different start now
---              -- elseif subtype ~= discretionarydisc_code then
---              --     prev    = getprev(start)
---              --     pglyph  = prev and getid(prev) == glyph_code
---              --     languages.expand(start,pglyph and prev)
---              -- end
---                 local pre, post, replace = getdisc(start)
---                 local indeed = false
---                 if pre then
---                     local okay = false
---                     if not prev then
---                         prev   = getprev(start)
---                         pglyph = prev and getid(prev) == glyph_code
---                     end
---                     if pglyph then
---                         pre, okay = inject_begin(pre,prev,keeptogether,krn,okay)
---                     end
---                     pre, okay = process_list(pre,keeptogether,krn,false,okay)
---                     if okay then
---                         indeed = true
---                     end
---                 end
---                 if post then
---                     local okay = false
---                     if not next then
---                         next   = getnext(start)
---                         nglyph = next and getid(next) == glyph_code
---                     end
---                     if nglyph then
---                         post, okay = inject_end(post,next,keeptogether,krn,okay)
---                     end
---                     post, okay = process_list(post,keeptogether,krn,false,okay)
---                     if okay then
---                         indeed = true
---                     end
---                 end
---                 if replace then
---                     local okay = false
---                     if not prev then
---                         prev    = getprev(start)
---                         pglyph  = prev and getid(prev) == glyph_code
---                     end
---                     if pglyph then
---                         replace, okay = inject_begin(replace,prev,keeptogether,krn,okay)
---                     end
---                     if not next then
---                         next   = getnext(start)
---                         nglyph = next and getid(next) == glyph_code
---                     end
---                     if nglyph then
---                         replace, okay = inject_end(replace,next,keeptogether,krn,okay)
---                     end
---                     replace, okay = process_list(replace,keeptogether,krn,false,okay)
---                     if okay then
---                         indeed = true
---                     end
---                 elseif prevfont then
---                     replace = new_kern(quaddata[prevfont]*krn)
---                     indeed  = true
---                 end
---                 if indeed then
---                     setdisc(start,pre,post,replace)
---                 end
---                 bound = false
---             elseif id == kern_code then
---                 bound  = getsubtype(start) == fontkern_code
---                 prev   = start
---                 previd = id
---             elseif id == glue_code then
---                 local subtype = getsubtype(start)
---                 if subtype == userskip_code or subtype == xspaceskip_code or subtype == spaceskip_code then
---                     local width, stretch, shrink, stretch_order, shrink_order = getglue(start)
---                     if width > 0 then
---                         local w = width + gluefactor * width * krn
---                         stretch = stretch * w / width
---                         shrink  = shrink  * w / width
---                         if fillup then
---                             stretch = 2 * stretch
---                             shrink  = 2 * shrink
---                             stretch_order = 1
---                          -- shrink_order  = 1 ?
---                         end
---                         setglue(start,w,stretch,shrink,stretch_order,shrink_order)
---                     end
---                 end
---                 bound = false
---             elseif id == hlist_code or id == vlist_code then
---                 local subtype = getsubtype(start)
---                 if subtype == unknownlist_code or subtype == boxlist_code then
---                     -- special case
---                     local b, f = closest_bound(start,getprev)
---                     if b then
---                         insert_node_before(head,start,kern_injector(fillup,quaddata[f]*krn))
---                     end
---                     local b, f = closest_bound(start,getnext)
---                     if b then
---                         insert_node_after(head,start,kern_injector(fillup,quaddata[f]*krn))
---                     end
---                 end
---                 bound = false
---             elseif id == math_code then
---                 start = end_of_math(start)
---                 bound = false
---             end
---             if start then
---                 start = getnext(start)
---             end
---         elseif id == kern_code then
---             bound  = getsubtype(start) == fontkern_code
---             prev   = start
---             previd = id
---             start  = getnext(start)
---         else
---             bound = false
---             start = getnext(start)
---         end
---     end
---     return head
--- end
-
 function kerns.handler(head)
     local start        = head
     local lastfont     = nil
@@ -601,7 +397,6 @@
                 if keepligature and keepligature(start) then
                     -- keep 'm
                 else
-                 -- head, start = use_components(head,start)
                     -- beware, these are not kerned so we mighty need a kern only pass
                     -- maybe some day .. anyway, one should disable ligaturing
                     local data = chardata[font][char]

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/typo-rep.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/typo-rep.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/typo-rep.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -28,7 +28,7 @@
 
 local getattr         = nuts.getattr
 
-local delete_node     = nuts.delete
+local remove_node     = nuts.remove
 local replace_node    = nuts.replace
 local copy_node       = nuts.copy
 
@@ -62,7 +62,7 @@
         if trace_stripping then
             report_stripping("deleting %C from text",char)
         end
-        head, current = delete_node(head,current)
+        head, current = remove_node(head,current,true)
     elseif type(what) == "function" then
         head, current = what(head,current)
         current = getnext(current)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-copas.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-copas.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-soc-imp-copas.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -1,6 +1,11 @@
 -- original file : copas.lua
--- for more into : see util-soc.lua
+-- for more info : see util-soc.lua
+-- copyright     : see below
+-- comment       : this version is a it cleaned up and adapted
 
+-- there is an official update but i'll wait till it is stable before i check
+-- it out (after all what we have now seems to work ok)
+
 local socket = socket or require("socket")
 local ssl    = ssl or nil -- only loaded upon demand
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-str.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-str.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-str.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -1273,7 +1273,6 @@
             f = function() return str end
         end
     end
- -- if jit then jit.on(f,true) end
     t[str] = f
     return f
 end

Modified: trunk/Master/texmf-dist/tex/context/modules/mkiv/s-math-ligatures.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkiv/s-math-ligatures.mkiv	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/modules/mkiv/s-math-ligatures.mkiv	2020-03-16 21:11:40 UTC (rev 54364)
@@ -31,20 +31,21 @@
 
 \continueifinputfile{s-math-ligatures.mkiv}
 
-\setupbodyfont[dejavu,10pt]
+\usemodule[article-basics] \setuplayout[tight] \setupbodyfont[10pt]
 
-\setuplayout
-  [width=middle,
-   height=middle,
-   topspace=15mm,
-   backspace=15mm,
-   bottomspace=15mm,
-   header=1cm,
-   headerdistance=0.5cm,
-   footer=0pt]
-
 \starttext
 
-    \showmathligatures
+\showmathligatures
 
+\blank[2*big]
+
+\starttyping
+sp = special
+ml = mathlist
+
+\setupmathematics[collapsing=1] : special
+\setupmathematics[collapsing=2] : special  mathlist
+\setupmathematics[collapsing=3] : mathlist special
+\stoptyping
+
 \stoptext

Modified: trunk/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -15,7 +15,7 @@
 local xmlsprint, xmlcprint, xmltext, xmlcontent, xmlempty = xml.sprint, xml.cprint, xml.text, xml.content, xml.empty
 local lxmlcollected, lxmlfilter = lxml.collected, lxml.filter
 local getid = lxml.getid
-local utfchar, utfcharacters, utfvalues, utfsplit, utflen = utf.char, utf.characters, utf.values, utf.split, utf.len
+local utfchar, utfcharacters, utfsplit, utflen = utf.char, utf.characters, utf.split, utf.len
 local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
 local P, Cs = lpeg.P, lpeg.Cs
 

Modified: trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-basics-nod.lua
===================================================================
--- trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-basics-nod.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-basics-nod.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -96,7 +96,6 @@
 nuts.getattr             = direct.get_attribute
 nuts.getboth             = direct.getboth
 nuts.getchar             = direct.getchar
-nuts.getcomponents       = direct.getcomponents
 nuts.getdirection        = direct.getdirection
 nuts.getdisc             = direct.getdisc
 nuts.getreplace          = direct.getreplace
@@ -137,7 +136,6 @@
 nuts.copy                = direct.copy
 nuts.copy_list           = direct.copy_list
 nuts.copy_node           = direct.copy
-nuts.delete              = direct.delete
 nuts.end_of_math         = direct.end_of_math
 nuts.flush               = direct.flush
 nuts.flush_list          = direct.flush_list
@@ -196,9 +194,8 @@
 local setlink       = nuts.setlink
 local getfield      = nuts.getfield
 local setfield      = nuts.setfield
-local getcomponents = nuts.getcomponents
-local setcomponents = nuts.setcomponents
-
+local getsubtype    = nuts.getsubtype
+local isglyph       = nuts.isglyph
 local find_tail     = nuts.tail
 local flush_list    = nuts.flush_list
 local flush_node    = nuts.flush_node
@@ -206,40 +203,72 @@
 local copy_node     = nuts.copy_node
 
 local glyph_code    = nodes.nodecodes.glyph
+local ligature_code = nodes.glyphcodes.ligature
 
-function nuts.copy_no_components(g,copyinjection)
-    local components = getcomponents(g)
-    if components then
-        setcomponents(g)
-        local n = copy_node(g)
-        if copyinjection then
-            copyinjection(n,g)
+do
+
+    local get_components = node.direct.getcomponents
+    local set_components = node.direct.setcomponents
+
+    local function copy_no_components(g,copyinjection)
+        local components = get_components(g)
+        if components then
+            set_components(g)
+            local n = copy_node(g)
+            if copyinjection then
+                copyinjection(n,g)
+            end
+            set_components(g,components)
+            -- maybe also upgrade the subtype but we don't use it anyway
+            return n
+        else
+            local n = copy_node(g)
+            if copyinjection then
+                copyinjection(n,g)
+            end
+            return n
         end
-        setcomponents(g,components)
-        -- maybe also upgrade the subtype but we don't use it anyway
-        return n
-    else
-        local n = copy_node(g)
-        if copyinjection then
-            copyinjection(n,g)
+    end
+
+    local function copy_only_glyphs(current)
+        local head     = nil
+        local previous = nil
+        for n in traverse_id(glyph_code,current) do
+            n = copy_node(n)
+            if head then
+                setlink(previous,n)
+            else
+                head = n
+            end
+            previous = n
         end
-        return n
+        return head
     end
-end
 
-function nuts.copy_only_glyphs(current)
-    local head     = nil
-    local previous = nil
-    for n in traverse_id(glyph_code,current) do
-        n = copy_node(n)
-        if head then
-            setlink(previous,n)
-        else
-            head = n
+    local function count_components(start,marks)
+        local char = isglyph(start)
+        if char then
+            if getsubtype(start) == ligature_code then
+                local n = 0
+                local components = get_components(start)
+                while components do
+                    n = n + count_components(components,marks)
+                    components = getnext(components)
+                end
+                return n
+            elseif not marks[char] then
+                return 1
+            end
         end
-        previous = n
+        return 0
     end
-    return head
+
+    nuts.set_components     = set_components
+    nuts.get_components     = get_components
+    nuts.copy_only_glyphs   = copy_only_glyphs
+    nuts.copy_no_components = copy_no_components
+    nuts.count_components   = count_components
+
 end
 
 nuts.uses_font = direct.uses_font

Modified: trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-core.lua
===================================================================
--- trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-core.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-core.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -7,7 +7,7 @@
 --     copyright = 'LuaTeX Development Team',
 -- }
 
-LUATEXCOREVERSION = 1.112 -- we reflect the luatex version where changes happened
+LUATEXCOREVERSION = 1.120 -- we reflect the luatex version where changes happened
 
 -- This file overloads some Lua functions. The readline variants provide the same
 -- functionality as LuaTeX <= 1.04 and doing it this way permits us to keep the
@@ -194,12 +194,20 @@
 
 if saferoption == 1 or shellescape ~= 1 then
 
+    package.loadlib      = function() end
+    package.searchers[4] = nil
+    package.searchers[3] = nil
+
     ffi = require('ffi')
-    for k, v in next, ffi do
-        if k ~= 'gc' then
-            ffi[k] = nil
+
+    if ffi then
+        for k, v in next, ffi do
+            if k ~= 'gc' then
+                ffi[k] = nil
+            end
         end
     end
+
     ffi = nil
 
 end

Modified: trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-fonts-merged.lua
===================================================================
--- trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-fonts-merged.lua	2020-03-16 21:05:56 UTC (rev 54363)
+++ trunk/Master/texmf-dist/tex/generic/context/luatex/luatex-fonts-merged.lua	2020-03-16 21:11:40 UTC (rev 54364)
@@ -1,6 +1,6 @@
 -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
 -- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date  : 2020-02-17 12:06
+-- merge date  : 2020-03-10 14:44
 
 do -- begin closure to overcome local limits and interference
 
@@ -4923,7 +4923,6 @@
 nuts.getattr=direct.get_attribute
 nuts.getboth=direct.getboth
 nuts.getchar=direct.getchar
-nuts.getcomponents=direct.getcomponents
 nuts.getdirection=direct.getdirection
 nuts.getdisc=direct.getdisc
 nuts.getreplace=direct.getreplace
@@ -4961,7 +4960,6 @@
 nuts.copy=direct.copy
 nuts.copy_list=direct.copy_list
 nuts.copy_node=direct.copy
-nuts.delete=direct.delete
 nuts.end_of_math=direct.end_of_math
 nuts.flush=direct.flush
 nuts.flush_list=direct.flush_list
@@ -5009,8 +5007,8 @@
 local setlink=nuts.setlink
 local getfield=nuts.getfield
 local setfield=nuts.setfield
-local getcomponents=nuts.getcomponents
-local setcomponents=nuts.setcomponents
+local getsubtype=nuts.getsubtype
+local isglyph=nuts.isglyph
 local find_tail=nuts.tail
 local flush_list=nuts.flush_list
 local flush_node=nuts.flush_node
@@ -5017,37 +5015,64 @@
 local traverse_id=nuts.traverse_id
 local copy_node=nuts.copy_node
 local glyph_code=nodes.nodecodes.glyph
-function nuts.copy_no_components(g,copyinjection)
- local components=getcomponents(g)
- if components then
-  setcomponents(g)
-  local n=copy_node(g)
-  if copyinjection then
-   copyinjection(n,g)
+local ligature_code=nodes.glyphcodes.ligature
+do
+ local get_components=node.direct.getcomponents
+ local set_components=node.direct.setcomponents
+ local function copy_no_components(g,copyinjection)
+  local components=get_components(g)
+  if components then
+   set_components(g)
+   local n=copy_node(g)
+   if copyinjection then
+    copyinjection(n,g)
+   end
+   set_components(g,components)
+   return n
+  else
+   local n=copy_node(g)
+   if copyinjection then
+    copyinjection(n,g)
+   end
+   return n
   end
-  setcomponents(g,components)
-  return n
- else
-  local n=copy_node(g)
-  if copyinjection then
-   copyinjection(n,g)
+ end
+ local function copy_only_glyphs(current)
+  local head=nil
+  local previous=nil
+  for n in traverse_id(glyph_code,current) do
+   n=copy_node(n)
+   if head then
+    setlink(previous,n)
+   else
+    head=n
+   end
+   previous=n
   end
-  return n
+  return head
  end
-end
-function nuts.copy_only_glyphs(current)
- local head=nil
- local previous=nil
- for n in traverse_id(glyph_code,current) do
-  n=copy_node(n)
-  if head then
-   setlink(previous,n)
-  else
-   head=n
+ local function count_components(start,marks)
+  local char=isglyph(start)
+  if char then
+   if getsubtype(start)==ligature_code then
+    local n=0
+    local components=get_components(start)
+    while components do
+     n=n+count_components(components,marks)
+     components=getnext(components)
+    end
+    return n
+   elseif not marks[char] then
+    return 1
+   end
   end
-  previous=n
+  return 0
  end
- return head
+ nuts.set_components=set_components
+ nuts.get_components=get_components
+ nuts.copy_only_glyphs=copy_only_glyphs
+ nuts.copy_no_components=copy_no_components
+ nuts.count_components=count_components
 end
 nuts.uses_font=direct.uses_font
 do
@@ -10354,7 +10379,7 @@
 local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match
 local formatters=string.formatters
 local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
-local rshift=bit32.rshift
+local idiv=number.idiv
 local trace_loading=false  trackers.register("fonts.loading",function(v) trace_loading=v end)
 local trace_mapping=false  trackers.register("fonts.mapping",function(v) trace_mapping=v end)
 local report_fonts=logs.reporter("fonts","loading")
@@ -10387,12 +10412,21 @@
 end
 local f_single=formatters["%04X"]
 local f_double=formatters["%04X%04X"]
+local s_unknown="FFFD"
 local function tounicode16(unicode)
  if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
   return f_single(unicode)
+ elseif unicode>=0x00E000 and unicode<=0x00F8FF then
+  return s_unknown
+ elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then
+  return s_unknown
+ elseif unicode>=0x100000 and unicode<=0x10FFFF then
+  return s_unknown
+ elseif unicode>=0x00D800 and unicode<=0x00DFFF then
+  return s_unknown
  else
   unicode=unicode-0x10000
-  return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+  return f_double(idiv(k,0x400)+0xD800,unicode%0x400+0xDC00)
  end
 end
 local function tounicode16sequence(unicodes)
@@ -10401,14 +10435,21 @@
   local u=unicodes[l]
   if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
    t[l]=f_single(u)
+  elseif unicode>=0x00E000 and unicode<=0x00F8FF then
+   t[l]=s_unknown
+  elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then
+   t[l]=s_unknown
+  elseif unicode>=0x100000 and unicode<=0x10FFFF then
+   t[l]=s_unknown
+  elseif unicode>=0x00D7FF and unicode<=0x00DFFF then
+   t[l]=s_unknown
   else
    u=u-0x10000
-   t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+   t[l]=f_double(idiv(k,0x400)+0xD800,u%0x400+0xDC00)
   end
  end
  return concat(t)
 end
-local unknown=f_single(0xFFFD)
 local hash={}
 local conc={}
 table.setmetatableindex(hash,function(t,k)
@@ -10416,7 +10457,7 @@
   v=f_single(k)
  else
   local k=k-0x10000
-  v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+  v=f_double(idiv(k,0x400)+0xD800,k%0x400+0xDC00)
  end
  t[k]=v
  return v
@@ -10429,11 +10470,13 @@
   end
   return concat(conc,"",1,n)
  elseif k>=0x00E000 and k<=0x00F8FF then
-  return unknown
+  return s_unknown
  elseif k>=0x0F0000 and k<=0x0FFFFF then
-  return unknown
+  return s_unknown
  elseif k>=0x100000 and k<=0x10FFFF then
-  return unknown
+  return s_unknown
+ elseif k>=0x00D7FF and k<=0x00DFFF then
+  return s_unknown
  else
   return hash[k]
  end
@@ -25929,7 +25972,6 @@
 local methods=allocate()
 analyzers.initializers=initializers
 analyzers.methods=methods
-local a_state=attributes.private('state')
 local nuts=nodes.nuts
 local tonut=nuts.tonut
 local getnext=nuts.getnext
@@ -25949,6 +25991,23 @@
 local chardata=characters and characters.data
 local otffeatures=fonts.constructors.features.otf
 local registerotffeature=otffeatures.register
+local setstate=nuts.setstate
+local getstate=nuts.getstate
+if not setstate or not getstate then
+ setstate=function(n,v)
+  setprop(n,"state",v)
+ end
+ getstate=function(n,v)
+  local s=getprop(n,"state")
+  if v then
+   return s==v
+  else
+   return s
+  end
+ end
+ nuts.setstate=setstate
+ nuts.getstate=getstate
+end
 local s_init=1 local s_rphf=7
 local s_medi=2 local s_half=8
 local s_fina=3 local s_pref=9
@@ -25996,36 +26055,36 @@
  current=tonut(current)
  while current do
   local char,id=ischar(current,font)
-  if char and not getprop(current,a_state) then
+  if char and not getstate(current) then
    done=true
    local d=descriptions[char]
    if d then
     if d.class=="mark" then
      done=true
-     setprop(current,a_state,s_mark)
+     setstate(current,s_mark)
     elseif useunicodemarks and categories[char]=="mn" then
      done=true
-     setprop(current,a_state,s_mark)
+     setstate(current,s_mark)
     elseif n==0 then
      first,last,n=current,current,1
-     setprop(current,a_state,s_init)
+     setstate(current,s_init)
     else
      last,n=current,n+1
-     setprop(current,a_state,s_medi)
+     setstate(current,s_medi)
     end
    else 
     if first and first==last then
-     setprop(last,a_state,s_isol)
+     setstate(last,s_isol)
     elseif last then
-     setprop(last,a_state,s_fina)
+     setstate(last,s_fina)
     end
     first,last,n=nil,nil,0
    end
   elseif char==false then
    if first and first==last then
-    setprop(last,a_state,s_isol)
+    setstate(last,s_isol)
    elseif last then
-    setprop(last,a_state,s_fina)
+    setstate(last,s_fina)
    end
    first,last,n=nil,nil,0
    if id==math_code then
@@ -26032,13 +26091,13 @@
     current=end_of_math(current)
    end
   elseif id==disc_code then
-   setprop(current,a_state,s_medi)
+   setstate(current,s_medi)
    last=current
   else 
    if first and first==last then
-    setprop(last,a_state,s_isol)
+    setstate(last,s_isol)
    elseif last then
-    setprop(last,a_state,s_fina)
+    setstate(last,s_fina)
    end
    first,last,n=nil,nil,0
    if id==math_code then
@@ -26048,9 +26107,9 @@
   current=getnext(current)
  end
  if first and first==last then
-  setprop(last,a_state,s_isol)
+  setstate(last,s_isol)
  elseif last then
-  setprop(last,a_state,s_fina)
+  setstate(last,s_fina)
  end
  return head,done
 end
@@ -26154,87 +26213,87 @@
  current=tonut(current)
  while current do
   local char,id=ischar(current,font)
-  if char and not getprop(current,a_state) then
+  if char and not getstate(current) then
    done=true
    local classifier=classifiers[char]
    if not classifier then
     if last then
      if c_last==s_medi or c_last==s_fina then
-      setprop(last,a_state,s_fina)
+      setstate(last,s_fina)
      else
       warning(last,"fina")
-      setprop(last,a_state,s_error)
+      setstate(last,s_error)
      end
      first,last=nil,nil
     elseif first then
      if c_first==s_medi or c_first==s_fina then
-      setprop(first,a_state,s_isol)
+      setstate(first,s_isol)
      else
       warning(first,"isol")
-      setprop(first,a_state,s_error)
+      setstate(first,s_error)
      end
      first=nil
     end
    elseif classifier==s_mark then
-    setprop(current,a_state,s_mark)
+    setstate(current,s_mark)
    elseif classifier==s_isol then
     if last then
      if c_last==s_medi or c_last==s_fina then
-      setprop(last,a_state,s_fina)
+      setstate(last,s_fina)
      else
       warning(last,"fina")
-      setprop(last,a_state,s_error)
+      setstate(last,s_error)
      end
      first,last=nil,nil
     elseif first then
      if c_first==s_medi or c_first==s_fina then
-      setprop(first,a_state,s_isol)
+      setstate(first,s_isol)
      else
       warning(first,"isol")
-      setprop(first,a_state,s_error)
+      setstate(first,s_error)
      end
      first=nil
     end
-    setprop(current,a_state,s_isol)
+    setstate(current,s_isol)
    elseif classifier==s_medi then
     if first then
      last=current
      c_last=classifier
-     setprop(current,a_state,s_medi)
+     setstate(current,s_medi)
     else
-     setprop(current,a_state,s_init)
+     setstate(current,s_init)
      first=current
      c_first=classifier
     end
    elseif classifier==s_fina then
     if last then
-     if getprop(last,a_state)~=s_init then
-      setprop(last,a_state,s_medi)
+     if getstate(last)~=s_init then
+      setstate(last,s_medi)
      end
-     setprop(current,a_state,s_fina)
+     setstate(current,s_fina)
      first,last=nil,nil
     elseif first then
-     setprop(current,a_state,s_fina)
+     setstate(current,s_fina)
      first=nil
     else
-     setprop(current,a_state,s_isol)
+     setstate(current,s_isol)
     end
    else 
-    setprop(current,a_state,s_rest)
+    setstate(current,s_rest)
     if last then
      if c_last==s_medi or c_last==s_fina then
-      setprop(last,a_state,s_fina)
+      setstate(last,s_fina)
      else
       warning(last,"fina")
-      setprop(last,a_state,s_error)
+      setstate(last,s_error)
      end
      first,last=nil,nil
     elseif first then
      if c_first==s_medi or c_first==s_fina then
-      setprop(first,a_state,s_isol)
+      setstate(first,s_isol)
      else
       warning(first,"isol")
-      setprop(first,a_state,s_error)
+      setstate(first,s_error)
      end
      first=nil
     end
@@ -26242,18 +26301,18 @@
   else
    if last then
     if c_last==s_medi or c_last==s_fina then
-     setprop(last,a_state,s_fina)
+     setstate(last,s_fina)
     else
      warning(last,"fina")
-     setprop(last,a_state,s_error)
+     setstate(last,s_error)
     end
     first,last=nil,nil
    elseif first then
     if c_first==s_medi or c_first==s_fina then
-     setprop(first,a_state,s_isol)
+     setstate(first,s_isol)
     else
      warning(first,"isol")
-     setprop(first,a_state,s_error)
+     setstate(first,s_error)
     end
     first=nil
    end
@@ -26265,17 +26324,17 @@
  end
  if last then
   if c_last==s_medi or c_last==s_fina then
-   setprop(last,a_state,s_fina)
+   setstate(last,s_fina)
   else
    warning(last,"fina")
-   setprop(last,a_state,s_error)
+   setstate(last,s_error)
   end
  elseif first then
   if c_first==s_medi or c_first==s_fina then
-   setprop(first,a_state,s_isol)
+   setstate(first,s_isol)
   else
    warning(first,"isol")
-   setprop(first,a_state,s_error)
+   setstate(first,s_error)
   end
  end
  return head,done
@@ -26355,8 +26414,7 @@
 local getboth=nuts.getboth
 local setboth=nuts.setboth
 local getid=nuts.getid
-local getprop=nuts.getprop
-local setprop=nuts.setprop
+local getstate=nuts.getstate
 local getsubtype=nuts.getsubtype
 local setsubtype=nuts.setsubtype
 local getchar=nuts.getchar
@@ -26365,13 +26423,15 @@
 local setdisc=nuts.setdisc
 local getreplace=nuts.getreplace
 local setlink=nuts.setlink
-local getcomponents=nuts.getcomponents 
-local setcomponents=nuts.setcomponents 
 local getwidth=nuts.getwidth
 local getattr=nuts.getattr
 local getglyphdata=nuts.getglyphdata
+local copy_no_components=nuts.copy_no_components
+local copy_only_glyphs=nuts.copy_only_glyphs
+local count_components=nuts.count_components
+local set_components=nuts.set_components
+local get_components=nuts.get_components
 local ischar=nuts.ischar
-local isglyph=nuts.isglyph
 local usesfont=nuts.uses_font
 local insert_node_after=nuts.insert_after
 local copy_node=nuts.copy
@@ -26396,7 +26456,6 @@
 local localpar_code=nodecodes.localpar
 local discretionarydisc_code=disccodes.discretionary
 local ligatureglyph_code=glyphcodes.ligature
-local a_state=attributes.private('state')
 local a_noligature=attributes.private("noligature")
 local injections=nodes.injections
 local setmark=injections.setmark
@@ -26557,27 +26616,6 @@
  end
  setdisc(disc,pre,post,replace)
 end
-local copy_no_components=nuts.copy_no_components
-local copy_only_glyphs=nuts.copy_only_glyphs
-local set_components=setcomponents
-local take_components=getcomponents
-local function count_components(start,marks)
- local char=isglyph(start)
- if char then
-  if getsubtype(start)==ligatureglyph_code then
-   local i=0
-   local components=getcomponents(start)
-   while components do
-    i=i+count_components(components,marks)
-    components=getnext(components)
-   end
-   return i
-  elseif not marks[char] then
-   return 1
-  end
- end
- return 0
-end
 local function markstoligature(head,start,stop,char)
  if start==stop and getchar(start)==char then
   return head,start
@@ -26623,7 +26661,7 @@
  setlink(prev,base,next)
  if not discfound then
   local deletemarks=not skiphash or hasmarks
-  local components=start
+  local components=start 
   local baseindex=0
   local componentindex=0
   local head=base
@@ -26669,7 +26707,6 @@
    local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true)
    if not replace then
     local prev=getprev(base)
-    local comp=take_components(base)
     local copied=copy_only_glyphs(comp)
     if pre then
      setlink(discprev,pre)
@@ -26676,10 +26713,10 @@
     else
      setnext(discprev) 
     end
-    pre=comp
+    pre=comp 
     if post then
      setlink(posttail,discnext)
-     setprev(post)
+     setprev(post) 
     else
      post=discnext
      setprev(discnext) 
@@ -28863,7 +28900,7 @@
  end
  local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
  local renewed=false
- if (post or replace) then 
+ if post or replace then 
   if post then
    setlink(posttail,next)
   else
@@ -29056,7 +29093,7 @@
           ss=nil
          end
         end
-lookupmatch=lg
+        lookupmatch=lg
        else
         break
        end
@@ -29091,7 +29128,7 @@
    if n==last then
     break
    end
-   local char=ischar(n)
+   local char=ischar(n,font)
    if char then
     local lookupmatch=lookupcache[char]
     if lookupmatch then
@@ -29210,7 +29247,7 @@
            ss=nil
           end
          end
-lookupmatch=lg
+         lookupmatch=lg
         else
          break
         end
@@ -29433,10 +29470,10 @@
         if lookupmatch then
          local a 
          if attr then
-          if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+          if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then
            a=true
           end
-         elseif not attribute or getprop(start,a_state)==attribute then
+         elseif not attribute or getstate(start,attribute) then
           a=true
          end
          if a then
@@ -29489,10 +29526,10 @@
         if m then
          local a 
          if attr then
-          if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+          if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then
            a=true
           end
-         elseif not attribute or getprop(start,a_state)==attribute then
+         elseif not attribute or getstate(start,attribute) then
           a=true
          end
          if a then
@@ -29935,6 +29972,8 @@
 local setchar=nuts.setchar
 local getprop=nuts.getprop
 local setprop=nuts.setprop
+local getstate=nuts.getstate
+local setstate=nuts.setstate
 local ischar=nuts.ischar
 local insert_node_after=nuts.insert_after
 local copy_node=nuts.copy
@@ -29944,7 +29983,6 @@
 local copyinjection=nodes.injections.copy 
 local unsetvalue=attributes.unsetvalue
 local fontdata=fonts.hashes.identifiers
-local a_state=attributes.private('state')
 local a_syllabe=attributes.private('syllabe')
 local dotted_circle=0x25CC
 local c_nbsp=0x00A0
@@ -30677,7 +30715,7 @@
    current=start
   else
    current=getnext(n)
-   setprop(start,a_state,s_rphf)
+   setstate(start,s_rphf)
   end
  end
  if getchar(current)==c_nbsp then
@@ -30710,9 +30748,9 @@
       local nextcurrent=copy_node(current)
       copyinjection(nextcurrent,current) 
       setlink(tempcurrent,nextcurrent)
-      setprop(tempcurrent,a_state,s_blwf)
+      setstate(tempcurrent,s_blwf)
       tempcurrent=processcharacters(tempcurrent,font)
-      setprop(tempcurrent,a_state,unsetvalue)
+      setstate(tempcurrent,unsetvalue)
       if getchar(next)==getchar(tempcurrent) then
        flush_list(tempcurrent)
        if show_syntax_errors then
@@ -30736,7 +30774,7 @@
  while not basefound do
   local char=getchar(current)
   if consonant[char] then
-   setprop(current,a_state,s_half)
+   setstate(current,s_half)
    if not firstcons then
     firstcons=current
    end
@@ -30744,9 +30782,9 @@
    if not base then
     base=current
    elseif blwfcache[char] then
-    setprop(current,a_state,s_blwf)
+    setstate(current,s_blwf)
    elseif pstfcache[char] then
-    setprop(current,a_state,s_pstf)
+    setstate(current,s_pstf)
    else
     base=current
    end
@@ -30811,14 +30849,14 @@
  while current~=stop do
   local next=getnext(current)
   if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then
-   setprop(current,a_state,unsetvalue)
+   setstate(current,unsetvalue)
   end
   current=next
  end
- if base~=stop and getprop(base,a_state) then 
+ if base~=stop and getstate(base) then 
   local next=getnext(base)
   if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then
-   setprop(base,a_state,unsetvalue)
+   setstate(base,unsetvalue)
   end
  end
  local current,allreordered,moved=start,false,{ [base]=true }
@@ -30955,7 +30993,7 @@
      end
      bn=next
     end
-    if getprop(current,a_state)==s_rphf then
+    if getstate(current,s_rphf) then
      if b~=current then
       if current==start then
        if head==start then
@@ -31106,7 +31144,7 @@
    while current do
     local char=ischar(current,startfont)
     if char and getprop(current,a_syllabe)==startattr then
-     if consonant[char] and not getprop(current,a_state)==s_pref then
+     if consonant[char] and not getstate(current,s_pref) then
       startnext=getnext(start)
       head=remove_node(head,start)
       setlink(current,start)
@@ -31130,7 +31168,7 @@
    while current do
     local char=ischar(current,startfont)
     if char and getprop(current,a_syllabe)==startattr then
-     if getprop(current,a_state)==s_pstf then 
+     if getstate(current,s_pstf) then 
       startnext=getnext(start)
       head=remove_node(head,start)
       setlink(getprev(current),start)
@@ -31163,7 +31201,7 @@
   while current do
    local char=ischar(current,startfont)
    if char and getprop(current,a_syllabe)==startattr then
-    local state=getprop(current,a_state)
+    local state=getstate(current)
     if before_subscript[rephbase] and (state==s_blwf or state==s_pstf) then
      c=current
     elseif after_subscript[rephbase] and (state==s_pstf) then
@@ -31243,7 +31281,7 @@
  local current=getprev(start)
  while current and getprop(current,a_syllabe)==startattr do
   local char=ischar(current)
-  if (not dependent_vowel[char] and not getprop(current,a_state) or getprop(current,a_state)==s_init) then
+  if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then
    startnext=getnext(start)
    head=remove_node(head,start)
    if current==head then
@@ -31323,7 +31361,7 @@
        if afternext and zw_char[getchar(afternext)] then 
         current=afternext 
        elseif current==start then
-        setprop(current,a_state,s_rphf)
+        setstate(current,s_rphf)
         current=next
        else
         current=next
@@ -31343,9 +31381,9 @@
      if found then 
       local next=getnext(current)
       if found[getchar(next)] or contextchain(found,next) then
-       if (not getprop(current,a_state) and not getprop(next,a_state)) then	
-        setprop(current,a_state,s_pref)
-        setprop(next,a_state,s_pref)
+       if (not getstate(current) and not getstate(next)) then	
+        setstate(current,s_pref)
+        setstate(next,s_pref)
         current=next
        end
       end
@@ -31365,8 +31403,8 @@
       if found[getchar(next)] or contextchain(found,next) then
        if next~=stop and getchar(getnext(next))==c_zwnj then 
         current=next
-       elseif (not getprop(current,a_state)) then	
-        setprop(current,a_state,s_half)
+       elseif (not getstate(current)) then	
+        setstate(current,s_half)
         if not halfpos then
          halfpos=current
         end
@@ -31387,9 +31425,9 @@
      if found then
       local next=getnext(current)
       if found[getchar(next)] or contextchain(found,next) then
-       if (not getprop(current,a_state) and not getprop(next,a_state)) then	
-        setprop(current,a_state,s_blwf)
-        setprop(next,a_state,s_blwf)
+       if (not getstate(current) and not getstate(next)) then 
+        setstate(current,s_blwf)
+        setstate(next,s_blwf)
         current=next
         subpos=current
        end
@@ -31408,9 +31446,9 @@
      if found then
       local next=getnext(current)
       if found[getchar(next)] or contextchain(found,next) then
-       if (not getprop(current,a_state) and not getprop(next,a_state)) then	
-        setprop(current,a_state,s_pstf)
-        setprop(next,a_state,s_pstf)
+       if (not getstate(current) and not getstate(next)) then 
+        setstate(current,s_pstf)
+        setstate(next,s_pstf)
         current=next
         postpos=current
        end
@@ -31422,7 +31460,7 @@
   end
  end
  local current,base,firstcons=start,nil,nil
- if getprop(start,a_state)==s_rphf then
+ if getstate(start,s_rphf) then
   current=getnext(getnext(start))
  end
  if current~=getnext(stop) and getchar(current)==c_nbsp then
@@ -31449,13 +31487,13 @@
       local tmp=getnext(next)
       local changestop=next==stop
       setnext(next)
-      setprop(current,a_state,s_pref)
+      setstate(current,s_pref)
       current=processcharacters(current,font)
-      setprop(current,a_state,s_blwf)
+      setstate(current,s_blwf)
       current=processcharacters(current,font)
-      setprop(current,a_state,s_pstf)
+      setstate(current,s_pstf)
       current=processcharacters(current,font)
-      setprop(current,a_state,unsetvalue)
+      setstate(current,unsetvalue)
       if halant[getchar(current)] then
        setnext(getnext(current),tmp)
        if show_syntax_errors then
@@ -31480,7 +31518,7 @@
      if not firstcons then
       firstcons=current
      end
-     local a=getprop(current,a_state)
+     local a=getstate(current)
      if not (a==s_blwf or a==s_pstf or (a~=s_rphf and a~=s_blwf and ra[getchar(current)])) then
       base=current
      end
@@ -31493,13 +31531,13 @@
   end
  end
  if not base then
-  if getprop(start,a_state)==s_rphf then
-   setprop(start,a_state,unsetvalue)
+  if getstate(start,s_rphf) then
+   setstate(start,unsetvalue)
   end
   return head,stop,nbspaces
  else
-  if getprop(base,a_state) then 
-   setprop(base,a_state,unsetvalue)
+  if getstate(base) then 
+   setstate(base,unsetvalue)
   end
   basepos=base
  end
@@ -31545,7 +31583,7 @@
     end
     local ppos=getprev(pos) 
     while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) do
-     if getprop(ppos,a_state)==s_pref then
+     if getstate(ppos,s_pref) then
       pos=ppos
      end
      ppos=getprev(ppos)
@@ -31617,7 +31655,7 @@
  while current~=last do
   local char=getchar(current)
   local cn=getnext(current)
-  if halant[char] and ra[ischar(cn)] and getprop(cn,a_state)~=s_rphf and getprop(cn,a_state)~=s_blwf then
+  if halant[char] and ra[ischar(cn)] and (not getstate(cn,s_rphf)) and (not getstate(cn,s_blwf)) then
    if after_main[ischar(cn)] then
     local prev=getprev(current)
     local next=getnext(cn)
@@ -32217,8 +32255,8 @@
  while current do
   local char=ischar(current,font)
   if char then
-			if n==0 and not getprop(current,a_state) then
-				setprop(current,a_state,s_init)
+			if n==0 and not getstate(current) then
+				setstate(current,s_init)
 			end
 			n=n+1
 		else
@@ -32294,7 +32332,7 @@
   end
   if not syllableend and show_syntax_errors then
    local char=ischar(current,font)
-   if char and not getprop(current,a_state) then 
+   if char and not getstate(current) then 
     local mark=mark_four[char]
     if mark then
      head,current=inject_syntax_error(head,current,char)
@@ -32312,8 +32350,8 @@
  while current do
   local char=ischar(current,font)
   if char then
-			if n==0 and not getprop(current,a_state) then	
-				setprop(current,a_state,s_init)
+			if n==0 and not getstate(current) then 
+				setstate(current,s_init)
 			end
 			n=n+1
 		else



More information about the tex-live-commits mailing list.