From 91a47fa6fbfacd23d2802c41d3c908569070bdf2 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Thu, 7 Jan 2021 17:18:53 +0100
Subject: 2021-01-07 16:59:00

---
 .../lexers/data/scite-context-data-context.lua     |   2 +-
 .../context/scite-context-data-context.properties  |   5 +-
 .../context/data/scite-context-data-context.lua    |   2 +-
 .../context/syntaxes/context-syntax-tex.json       |   2 +-
 .../documents/general/manuals/luametatex.pdf       | Bin 1386861 -> 1383227 bytes
 scripts/context/lua/mtx-fonts.lua                  |   2 +-
 tex/context/base/mkii/cont-new.mkii                |   2 +-
 tex/context/base/mkii/context.mkii                 |   2 +-
 tex/context/base/mkii/mult-en.mkii                 |   1 +
 tex/context/base/mkiv/cont-new.mkiv                |   2 +-
 tex/context/base/mkiv/context.mkiv                 |   2 +-
 tex/context/base/mkiv/font-cff.lua                 |  15 +-
 tex/context/base/mkiv/font-dsp.lua                 |   4 +-
 tex/context/base/mkiv/font-mis.lua                 |   2 +-
 tex/context/base/mkiv/font-otl.lua                 |   2 +-
 tex/context/base/mkiv/font-ots.lua                 |   3 +
 tex/context/base/mkiv/mult-low.lua                 |   3 +-
 tex/context/base/mkiv/status-files.pdf             | Bin 26485 -> 26130 bytes
 tex/context/base/mkiv/status-lua.pdf               | Bin 253534 -> 253886 bytes
 tex/context/base/mkiv/task-ini.lua                 |   1 +
 tex/context/base/mkxl/cont-new.mkxl                |   2 +-
 tex/context/base/mkxl/context.mkxl                 |   2 +-
 tex/context/base/mkxl/driv-shp.lmt                 |   5 +-
 tex/context/base/mkxl/font-col.lmt                 |  54 +-
 tex/context/base/mkxl/font-ctx.lmt                 |  10 +-
 tex/context/base/mkxl/font-ini.mklx                | 110 ++--
 tex/context/base/mkxl/font-mat.mklx                |  71 ++-
 tex/context/base/mkxl/font-ots.lmt                 | 688 ++++++++++-----------
 tex/context/base/mkxl/lang-ini.mkxl                |  18 +-
 tex/context/base/mkxl/node-fnt.lmt                 | 162 ++---
 tex/context/base/mkxl/node-nut.lmt                 |   2 +-
 tex/context/base/mkxl/node-tra.lmt                 |  15 +
 tex/context/interface/mkii/keys-en.xml             |   1 +
 tex/context/modules/mkiv/s-fonts-variable.mkiv     |   6 +
 tex/generic/context/luatex/luatex-fonts-merged.lua |  14 +-
 35 files changed, 628 insertions(+), 584 deletions(-)

diff --git a/context/data/scite/context/lexers/data/scite-context-data-context.lua b/context/data/scite/context/lexers/data/scite-context-data-context.lua
index 34112fbd2..87ed1974d 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-context.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-context.lua
@@ -1,4 +1,4 @@
 return {
  ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "pluseleven", "plustwelve", "plussixteen", "plusfifty", "plushundred", "plusonehundred", "plustwohundred", "plusfivehundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "maxcardminusone", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxcount", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "directionlefttoright", "directionrighttoleft", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "contextformat", "contextversion", "contextlmtxmode", "contextmark", "mksuffix", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "ctdcatcodes", "rlncatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "commaasciicode", "spaceasciicode", "periodasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "leftparentasciicode", "rightparentasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "hyphenasciicode", "percentasciicode", "leftbracketasciicode", "rightbracketasciicode", "frozenhsizecode", "frozenskipcode", "frozenhangcode", "frozenindentcode", "frozenparfillcode", "frozenadjustcode", "frozenprotrudecode", "frozentolerancecode", "frozenstretchcode", "frozenloosenesscode", "frozenlastlinecode", "frozenlinepenaltycode", "frozenclubpenaltycode", "frozenwidowpenaltycode", "frozendisplaypenaltycode", "frozenbrokenpenaltycode", "frozendemeritscode", "frozenshapecode", "frozenlinecode", "frozenallcode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vadjustgroupcode", "vcentergroupcode", "mathabovegroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "localboxgroupcode", "splitoffgroupcode", "splitkeepgroupcode", "preamblegroupcode", "alignsetgroupcode", "finrowgroupcode", "discretionarygroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "mathexheight", "mathemwidth", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathaxisheight", "muquad", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifelsemode", "doifmodeelse", "doifnotmode", "startmodeset", "stopmodeset", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifelseallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", "doifelsedocumentvariable", "doifdocumentvariableelse", "doifdocumentvariable", "doifnotdocumentvariable", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "everystarttext", "everystoptext", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "definemode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "lrm", "rlm", "bidilre", "bidirle", "bidipop", "bidilro", "bidirlo", "breakablethinspace", "nobreakspace", "nonbreakablespace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "enquad", "emquad", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj", "optionalspace", "asciispacechar", "softhyphen", "Ux", "eUx", "Umathaccents", "parfillleftskip", "parfillrightskip", "startlmtxmode", "stoplmtxmode", "startmkivmode", "stopmkivmode", "wildcardsymbol", "normalhyphenationmodecode", "automatichyphenationmodecode", "explicithyphenationmodecode", "syllablehyphenationmodecode", "uppercasehyphenationmodecode", "completehyphenationmodecode", "compoundhyphenationmodecode", "strictstarthyphenationmodecode", "strictendhyphenationmodecode", "automaticpenaltyhyphenationmodecode", "explicitpenaltyhyphenationmodecode", "permitgluehyphenationmodecode", "permitallhyphenationmodecode", "permitmathreplacehyphenationmodecode", "normalizelinecode", "parindentskipcode", "swaphangindentcode", "swapparsshapecode", "breakafterdircode", "removemarginkernscode", "noligaturingcode", "nokerningcode", "noleftligaturecode", "noleftkerncode", "norightligaturecode", "norightkerncode", "noexpansioncode", "noprotrusioncode", "frozenflagcode", "tolerantflagcode", "protectedflagcode", "primitiveflagcode", "permanentflagcode", "noalignedflagcode", "immutableflagcode", "mutableflagcode", "globalflagcode", "overloadedflagcode", "immediateflagcode", "conditionalflagcode", "valueflagcode", "instanceflagcode", "continuewhenlmtxmode" },
- ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "copysetups", "resetsetups", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "globalsetmode", "globalresetmode", "globalsetsystemmode", "globalresetsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "autorule", "strippedcsname", "checkedstrippedcsname", "nofarguments", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthargumenttrue", "sixthargumentfalse", "sixthargumenttrue", "seventhargumentfalse", "seventhargumenttrue", "vkern", "hkern", "vpenalty", "hpenalty", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "startpickupmath", "stoppickupmath", "reqno", "mathortext", "thebox", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilll", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "normalhfilllneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilll", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "normalvfilllneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "scratchmacro", "scratchmacroone", "scratchmacrotwo", "scratchconditiontrue", "scratchconditionfalse", "ifscratchcondition", "scratchconditiononetrue", "scratchconditiononefalse", "ifscratchconditionone", "scratchconditiontwotrue", "scratchconditiontwofalse", "ifscratchconditiontwo", "globalscratchcounterone", "globalscratchcountertwo", "globalscratchcounterthree", "groupedcommand", "groupedcommandcs", "triggergroupedcommand", "triggergroupedcommandcs", "simplegroupedcommand", "pickupgroupedcommand", "usedbaselineskip", "usedlineskip", "usedlineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "next", "nexttoken", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "boxisempty", "givenwidth", "givenheight", "givendepth", "scangivendimensions", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchtotal", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "firstinset", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextcharcs", "doifnextcharcselse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doifelseassignmentcs", "doifassignmentelsecs", "validassignment", "novalidassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "quitcondition", "truecondition", "falsecondition", "tracingall", "tracingnone", "loggingall", "showluatokens", "aliasmacro", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeytabs", "obeypages", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "naturalspace", "controlspace", "normalspaces", "ignoretabs", "ignorelines", "ignorepages", "ignoreeofs", "setcontrolspaces", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "ignoreparskip", "forcestrutdepth", "onlynonbreakablespace", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "directmeasure", "setquantity", "setequantity", "setgquantity", "setxquantity", "definequantity", "freezequantity", "quantity", "quantitied", "directquantity", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "setexpandeddummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "doloopovermatch", "doloopovermatched", "doloopoverlist", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "setconditional", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "onlypdfobjectcompression", "nopdfobjectcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "shiftbox", "vpackbox", "hpackbox", "vpackedbox", "hpackedbox", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "superprescript", "subprescript", "nosuperprescript", "nosubsprecript", "uncramped", "cramped", "mathstyletrigger", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "ctxluamatch", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "installprotectedctxfunction", "installprotectedctxscanner", "installctxscanner", "resetctxscanner", "cldprocessfile", "cldloadfile", "cldloadviafile", "cldcontext", "cldcommand", "carryoverpar", "freezeparagraphproperties", "defrostparagraphproperties", "setparagraphfreezing", "forgetparagraphfreezing", "updateparagraphproperties", "updateparagraphpenalties", "updateparagraphdemerits", "updateparagraphshapes", "updateparagraphlines", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "Umathtopaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "checkedlefttoright", "checkedrighttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "dirlre", "dirrle", "dirlro", "dirrlo", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "compounddiscretionary", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "naturaltpack", "reversehbox", "reversevbox", "reversevtop", "reversehpack", "reversevpack", "reversetpack", "frule", "compoundhyphenpenalty", "start", "stop", "unsupportedcs", "openout", "closeout", "write", "openin", "closein", "read", "readline", "readfromterminal", "boxlines", "boxline", "setboxline", "copyboxline", "boxlinewd", "boxlineht", "boxlinedp", "boxlinenw", "boxlinenh", "boxlinend", "boxlinels", "boxliners", "boxlinelh", "boxlinerh", "boxlinelp", "boxlinerp", "boxlinein", "boxrangewd", "boxrangeht", "boxrangedp", "bitwiseset", "bitwiseand", "bitwiseor", "bitwisexor", "bitwisenot", "bitwisenil", "ifbitwiseand", "bitwise", "bitwiseshift", "bitwiseflip", "textdir", "linedir", "pardir", "boxdir", "prelistbox", "postlistbox", "prelistcopy", "postlistcopy", "setprelistbox", "setpostlistbox", "noligaturing", "nokerning", "noexpansion", "noprotrusion", "futureletnexttoken", "defbackslashbreak", "letbackslashbreak", "pushoverloadmode", "popoverloadmode" },
+ ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "copysetups", "resetsetups", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "globalsetmode", "globalresetmode", "globalsetsystemmode", "globalresetsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "autorule", "strippedcsname", "checkedstrippedcsname", "nofarguments", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthargumenttrue", "sixthargumentfalse", "sixthargumenttrue", "seventhargumentfalse", "seventhargumenttrue", "vkern", "hkern", "vpenalty", "hpenalty", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "startpickupmath", "stoppickupmath", "reqno", "mathortext", "thebox", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilll", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "normalhfilllneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilll", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "normalvfilllneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "scratchmacro", "scratchmacroone", "scratchmacrotwo", "scratchconditiontrue", "scratchconditionfalse", "ifscratchcondition", "scratchconditiononetrue", "scratchconditiononefalse", "ifscratchconditionone", "scratchconditiontwotrue", "scratchconditiontwofalse", "ifscratchconditiontwo", "globalscratchcounterone", "globalscratchcountertwo", "globalscratchcounterthree", "groupedcommand", "groupedcommandcs", "triggergroupedcommand", "triggergroupedcommandcs", "simplegroupedcommand", "pickupgroupedcommand", "usedbaselineskip", "usedlineskip", "usedlineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "next", "nexttoken", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "boxisempty", "givenwidth", "givenheight", "givendepth", "scangivendimensions", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchtotal", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "firstinset", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextcharcs", "doifnextcharcselse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doifelseassignmentcs", "doifassignmentelsecs", "validassignment", "novalidassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "quitcondition", "truecondition", "falsecondition", "tracingall", "tracingnone", "loggingall", "showluatokens", "aliasmacro", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeytabs", "obeypages", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "naturalspace", "controlspace", "normalspaces", "ignoretabs", "ignorelines", "ignorepages", "ignoreeofs", "setcontrolspaces", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "ignoreparskip", "forcestrutdepth", "onlynonbreakablespace", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "directmeasure", "setquantity", "setequantity", "setgquantity", "setxquantity", "definequantity", "freezequantity", "quantity", "quantitied", "directquantity", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "setexpandeddummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "doloopovermatch", "doloopovermatched", "doloopoverlist", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "setconditional", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "onlypdfobjectcompression", "nopdfobjectcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "shiftbox", "vpackbox", "hpackbox", "vpackedbox", "hpackedbox", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "superprescript", "subprescript", "nosuperprescript", "nosubsprecript", "uncramped", "cramped", "mathstyletrigger", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "ctxluamatch", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "installprotectedctxfunction", "installprotectedctxscanner", "installctxscanner", "resetctxscanner", "cldprocessfile", "cldloadfile", "cldloadviafile", "cldcontext", "cldcommand", "carryoverpar", "freezeparagraphproperties", "defrostparagraphproperties", "setparagraphfreezing", "forgetparagraphfreezing", "updateparagraphproperties", "updateparagraphpenalties", "updateparagraphdemerits", "updateparagraphshapes", "updateparagraphlines", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "Umathtopaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "checkedlefttoright", "checkedrighttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "dirlre", "dirrle", "dirlro", "dirrlo", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "compounddiscretionary", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "naturaltpack", "reversehbox", "reversevbox", "reversevtop", "reversehpack", "reversevpack", "reversetpack", "frule", "compoundhyphenpenalty", "start", "stop", "unsupportedcs", "openout", "closeout", "write", "openin", "closein", "read", "readline", "readfromterminal", "boxlines", "boxline", "setboxline", "copyboxline", "boxlinewd", "boxlineht", "boxlinedp", "boxlinenw", "boxlinenh", "boxlinend", "boxlinels", "boxliners", "boxlinelh", "boxlinerh", "boxlinelp", "boxlinerp", "boxlinein", "boxrangewd", "boxrangeht", "boxrangedp", "bitwiseset", "bitwiseand", "bitwiseor", "bitwisexor", "bitwisenot", "bitwisenil", "ifbitwiseand", "bitwise", "bitwiseshift", "bitwiseflip", "textdir", "linedir", "pardir", "boxdir", "prelistbox", "postlistbox", "prelistcopy", "postlistcopy", "setprelistbox", "setpostlistbox", "noligaturing", "nokerning", "noexpansion", "noprotrusion", "noleftkerning", "noleftligaturing", "norightkerning", "norightligaturing", "futureletnexttoken", "defbackslashbreak", "letbackslashbreak", "pushoverloadmode", "popoverloadmode" },
 }
\ No newline at end of file
diff --git a/context/data/scite/context/scite-context-data-context.properties b/context/data/scite/context/scite-context-data-context.properties
index e94618773..7ae113eec 100644
--- a/context/data/scite/context/scite-context-data-context.properties
+++ b/context/data/scite/context/scite-context-data-context.properties
@@ -277,6 +277,7 @@ bitwiseset bitwiseand bitwiseor bitwisexor bitwisenot \
 bitwisenil ifbitwiseand bitwise bitwiseshift bitwiseflip \
 textdir linedir pardir boxdir prelistbox \
 postlistbox prelistcopy postlistcopy setprelistbox setpostlistbox \
-noligaturing nokerning noexpansion noprotrusion futureletnexttoken \
-defbackslashbreak letbackslashbreak pushoverloadmode popoverloadmode 
+noligaturing nokerning noexpansion noprotrusion noleftkerning \
+noleftligaturing norightkerning norightligaturing futureletnexttoken defbackslashbreak \
+letbackslashbreak pushoverloadmode popoverloadmode 
 
diff --git a/context/data/textadept/context/data/scite-context-data-context.lua b/context/data/textadept/context/data/scite-context-data-context.lua
index 34112fbd2..87ed1974d 100644
--- a/context/data/textadept/context/data/scite-context-data-context.lua
+++ b/context/data/textadept/context/data/scite-context-data-context.lua
@@ -1,4 +1,4 @@
 return {
  ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "pluseleven", "plustwelve", "plussixteen", "plusfifty", "plushundred", "plusonehundred", "plustwohundred", "plusfivehundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "maxcardminusone", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxcount", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "directionlefttoright", "directionrighttoleft", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "contextformat", "contextversion", "contextlmtxmode", "contextmark", "mksuffix", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "ctdcatcodes", "rlncatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "commaasciicode", "spaceasciicode", "periodasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "leftparentasciicode", "rightparentasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "hyphenasciicode", "percentasciicode", "leftbracketasciicode", "rightbracketasciicode", "frozenhsizecode", "frozenskipcode", "frozenhangcode", "frozenindentcode", "frozenparfillcode", "frozenadjustcode", "frozenprotrudecode", "frozentolerancecode", "frozenstretchcode", "frozenloosenesscode", "frozenlastlinecode", "frozenlinepenaltycode", "frozenclubpenaltycode", "frozenwidowpenaltycode", "frozendisplaypenaltycode", "frozenbrokenpenaltycode", "frozendemeritscode", "frozenshapecode", "frozenlinecode", "frozenallcode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vadjustgroupcode", "vcentergroupcode", "mathabovegroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "localboxgroupcode", "splitoffgroupcode", "splitkeepgroupcode", "preamblegroupcode", "alignsetgroupcode", "finrowgroupcode", "discretionarygroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "mathexheight", "mathemwidth", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathaxisheight", "muquad", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifelsemode", "doifmodeelse", "doifnotmode", "startmodeset", "stopmodeset", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifelseallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", "doifelsedocumentvariable", "doifdocumentvariableelse", "doifdocumentvariable", "doifnotdocumentvariable", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "everystarttext", "everystoptext", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "definemode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "lrm", "rlm", "bidilre", "bidirle", "bidipop", "bidilro", "bidirlo", "breakablethinspace", "nobreakspace", "nonbreakablespace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "enquad", "emquad", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj", "optionalspace", "asciispacechar", "softhyphen", "Ux", "eUx", "Umathaccents", "parfillleftskip", "parfillrightskip", "startlmtxmode", "stoplmtxmode", "startmkivmode", "stopmkivmode", "wildcardsymbol", "normalhyphenationmodecode", "automatichyphenationmodecode", "explicithyphenationmodecode", "syllablehyphenationmodecode", "uppercasehyphenationmodecode", "completehyphenationmodecode", "compoundhyphenationmodecode", "strictstarthyphenationmodecode", "strictendhyphenationmodecode", "automaticpenaltyhyphenationmodecode", "explicitpenaltyhyphenationmodecode", "permitgluehyphenationmodecode", "permitallhyphenationmodecode", "permitmathreplacehyphenationmodecode", "normalizelinecode", "parindentskipcode", "swaphangindentcode", "swapparsshapecode", "breakafterdircode", "removemarginkernscode", "noligaturingcode", "nokerningcode", "noleftligaturecode", "noleftkerncode", "norightligaturecode", "norightkerncode", "noexpansioncode", "noprotrusioncode", "frozenflagcode", "tolerantflagcode", "protectedflagcode", "primitiveflagcode", "permanentflagcode", "noalignedflagcode", "immutableflagcode", "mutableflagcode", "globalflagcode", "overloadedflagcode", "immediateflagcode", "conditionalflagcode", "valueflagcode", "instanceflagcode", "continuewhenlmtxmode" },
- ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "copysetups", "resetsetups", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "globalsetmode", "globalresetmode", "globalsetsystemmode", "globalresetsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "autorule", "strippedcsname", "checkedstrippedcsname", "nofarguments", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthargumenttrue", "sixthargumentfalse", "sixthargumenttrue", "seventhargumentfalse", "seventhargumenttrue", "vkern", "hkern", "vpenalty", "hpenalty", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "startpickupmath", "stoppickupmath", "reqno", "mathortext", "thebox", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilll", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "normalhfilllneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilll", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "normalvfilllneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "scratchmacro", "scratchmacroone", "scratchmacrotwo", "scratchconditiontrue", "scratchconditionfalse", "ifscratchcondition", "scratchconditiononetrue", "scratchconditiononefalse", "ifscratchconditionone", "scratchconditiontwotrue", "scratchconditiontwofalse", "ifscratchconditiontwo", "globalscratchcounterone", "globalscratchcountertwo", "globalscratchcounterthree", "groupedcommand", "groupedcommandcs", "triggergroupedcommand", "triggergroupedcommandcs", "simplegroupedcommand", "pickupgroupedcommand", "usedbaselineskip", "usedlineskip", "usedlineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "next", "nexttoken", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "boxisempty", "givenwidth", "givenheight", "givendepth", "scangivendimensions", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchtotal", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "firstinset", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextcharcs", "doifnextcharcselse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doifelseassignmentcs", "doifassignmentelsecs", "validassignment", "novalidassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "quitcondition", "truecondition", "falsecondition", "tracingall", "tracingnone", "loggingall", "showluatokens", "aliasmacro", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeytabs", "obeypages", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "naturalspace", "controlspace", "normalspaces", "ignoretabs", "ignorelines", "ignorepages", "ignoreeofs", "setcontrolspaces", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "ignoreparskip", "forcestrutdepth", "onlynonbreakablespace", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "directmeasure", "setquantity", "setequantity", "setgquantity", "setxquantity", "definequantity", "freezequantity", "quantity", "quantitied", "directquantity", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "setexpandeddummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "doloopovermatch", "doloopovermatched", "doloopoverlist", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "setconditional", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "onlypdfobjectcompression", "nopdfobjectcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "shiftbox", "vpackbox", "hpackbox", "vpackedbox", "hpackedbox", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "superprescript", "subprescript", "nosuperprescript", "nosubsprecript", "uncramped", "cramped", "mathstyletrigger", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "ctxluamatch", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "installprotectedctxfunction", "installprotectedctxscanner", "installctxscanner", "resetctxscanner", "cldprocessfile", "cldloadfile", "cldloadviafile", "cldcontext", "cldcommand", "carryoverpar", "freezeparagraphproperties", "defrostparagraphproperties", "setparagraphfreezing", "forgetparagraphfreezing", "updateparagraphproperties", "updateparagraphpenalties", "updateparagraphdemerits", "updateparagraphshapes", "updateparagraphlines", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "Umathtopaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "checkedlefttoright", "checkedrighttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "dirlre", "dirrle", "dirlro", "dirrlo", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "compounddiscretionary", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "naturaltpack", "reversehbox", "reversevbox", "reversevtop", "reversehpack", "reversevpack", "reversetpack", "frule", "compoundhyphenpenalty", "start", "stop", "unsupportedcs", "openout", "closeout", "write", "openin", "closein", "read", "readline", "readfromterminal", "boxlines", "boxline", "setboxline", "copyboxline", "boxlinewd", "boxlineht", "boxlinedp", "boxlinenw", "boxlinenh", "boxlinend", "boxlinels", "boxliners", "boxlinelh", "boxlinerh", "boxlinelp", "boxlinerp", "boxlinein", "boxrangewd", "boxrangeht", "boxrangedp", "bitwiseset", "bitwiseand", "bitwiseor", "bitwisexor", "bitwisenot", "bitwisenil", "ifbitwiseand", "bitwise", "bitwiseshift", "bitwiseflip", "textdir", "linedir", "pardir", "boxdir", "prelistbox", "postlistbox", "prelistcopy", "postlistcopy", "setprelistbox", "setpostlistbox", "noligaturing", "nokerning", "noexpansion", "noprotrusion", "futureletnexttoken", "defbackslashbreak", "letbackslashbreak", "pushoverloadmode", "popoverloadmode" },
+ ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "copysetups", "resetsetups", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "globalsetmode", "globalresetmode", "globalsetsystemmode", "globalresetsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "autorule", "strippedcsname", "checkedstrippedcsname", "nofarguments", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthargumenttrue", "sixthargumentfalse", "sixthargumenttrue", "seventhargumentfalse", "seventhargumenttrue", "vkern", "hkern", "vpenalty", "hpenalty", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "startpickupmath", "stoppickupmath", "reqno", "mathortext", "thebox", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilll", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "normalhfilllneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilll", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "normalvfilllneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "scratchmacro", "scratchmacroone", "scratchmacrotwo", "scratchconditiontrue", "scratchconditionfalse", "ifscratchcondition", "scratchconditiononetrue", "scratchconditiononefalse", "ifscratchconditionone", "scratchconditiontwotrue", "scratchconditiontwofalse", "ifscratchconditiontwo", "globalscratchcounterone", "globalscratchcountertwo", "globalscratchcounterthree", "groupedcommand", "groupedcommandcs", "triggergroupedcommand", "triggergroupedcommandcs", "simplegroupedcommand", "pickupgroupedcommand", "usedbaselineskip", "usedlineskip", "usedlineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "next", "nexttoken", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "boxisempty", "givenwidth", "givenheight", "givendepth", "scangivendimensions", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchtotal", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "firstinset", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextcharcs", "doifnextcharcselse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doifelseassignmentcs", "doifassignmentelsecs", "validassignment", "novalidassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "quitcondition", "truecondition", "falsecondition", "tracingall", "tracingnone", "loggingall", "showluatokens", "aliasmacro", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeytabs", "obeypages", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "naturalspace", "controlspace", "normalspaces", "ignoretabs", "ignorelines", "ignorepages", "ignoreeofs", "setcontrolspaces", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "ignoreparskip", "forcestrutdepth", "onlynonbreakablespace", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "directmeasure", "setquantity", "setequantity", "setgquantity", "setxquantity", "definequantity", "freezequantity", "quantity", "quantitied", "directquantity", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "setexpandeddummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "doloopovermatch", "doloopovermatched", "doloopoverlist", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "setconditional", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "onlypdfobjectcompression", "nopdfobjectcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "shiftbox", "vpackbox", "hpackbox", "vpackedbox", "hpackedbox", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "superprescript", "subprescript", "nosuperprescript", "nosubsprecript", "uncramped", "cramped", "mathstyletrigger", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "ctxluamatch", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "installprotectedctxfunction", "installprotectedctxscanner", "installctxscanner", "resetctxscanner", "cldprocessfile", "cldloadfile", "cldloadviafile", "cldcontext", "cldcommand", "carryoverpar", "freezeparagraphproperties", "defrostparagraphproperties", "setparagraphfreezing", "forgetparagraphfreezing", "updateparagraphproperties", "updateparagraphpenalties", "updateparagraphdemerits", "updateparagraphshapes", "updateparagraphlines", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "Umathtopaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "checkedlefttoright", "checkedrighttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "dirlre", "dirrle", "dirlro", "dirrlo", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "compounddiscretionary", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "naturaltpack", "reversehbox", "reversevbox", "reversevtop", "reversehpack", "reversevpack", "reversetpack", "frule", "compoundhyphenpenalty", "start", "stop", "unsupportedcs", "openout", "closeout", "write", "openin", "closein", "read", "readline", "readfromterminal", "boxlines", "boxline", "setboxline", "copyboxline", "boxlinewd", "boxlineht", "boxlinedp", "boxlinenw", "boxlinenh", "boxlinend", "boxlinels", "boxliners", "boxlinelh", "boxlinerh", "boxlinelp", "boxlinerp", "boxlinein", "boxrangewd", "boxrangeht", "boxrangedp", "bitwiseset", "bitwiseand", "bitwiseor", "bitwisexor", "bitwisenot", "bitwisenil", "ifbitwiseand", "bitwise", "bitwiseshift", "bitwiseflip", "textdir", "linedir", "pardir", "boxdir", "prelistbox", "postlistbox", "prelistcopy", "postlistcopy", "setprelistbox", "setpostlistbox", "noligaturing", "nokerning", "noexpansion", "noprotrusion", "noleftkerning", "noleftligaturing", "norightkerning", "norightligaturing", "futureletnexttoken", "defbackslashbreak", "letbackslashbreak", "pushoverloadmode", "popoverloadmode" },
 }
\ No newline at end of file
diff --git a/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json b/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json
index 86b30048f..78ac92aa2 100644
--- a/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json
+++ b/context/data/vscode/extensions/context/syntaxes/context-syntax-tex.json
@@ -88,7 +88,7 @@
    "name" : "context.grouping.symbols.groups.tex"
   },
   "helper" : {
-   "match" : "\u005C\u005C(xmlsetup|writestatus|write|wait|vpenalty|vpackedbox|vpackbox|vkern|vglue|vfillneg|vfilllneg|vfilll|validassignment|uxdef|usedummystyleparameter|usedummystyleandcolor|usedummycolorparameter|usedlineskiplimit|usedlineskip|usedbaselineskip|updateparagraphshapes|updateparagraphproperties|updateparagraphpenalties|updateparagraphlines|updateparagraphdemerits|unvoidbox|unsupportedcs|unprotect|unique|unexpanded|undefinevalue|uncramped|ugdef|uedef|uedcatcodecommand|udef|twodigits|truecondition|tripleexpandafter|triggeruncrampedstyle|triggeruncrampedsmallstyle|triggeruncrampedbigstyle|triggertextstyle|triggersmallstyle|triggerscriptstyle|triggerscriptscriptstyle|triggermathstyle|triggergroupedcommandcs|triggergroupedcommand|triggerdisplaystyle|triggercrampedstyle|triggercrampedsmallstyle|triggercrampedbigstyle|triggerbigstyle|tracingnone|tracingall|to|threedigits|thirdofthreeunexpanded|thirdofthreearguments|thirdofsixarguments|thirdoffourarguments|thirdoffivearguments|thirdargumenttrue|thirdargumentfalse|then|thebox|textdir|texsetup|texdefinition|synchronizelayoutdirection|synchronizeinlinedirection|synchronizedisplaydirection|superscript|superprescript|subscript|subprescript|strutwd|struthtdp|strutht|strutgap|strutdp|strutbox|strut|strippedcsname|stopxmlsetups|stoptexsetups|stoptexdefinition|stoptexcode|stopsetups|stoprawsetups|stoppickupmath|stopnointerference|stopluasetups|stopluaparameterset|stopluacode|stoplua|stoplocalsetups|stopimath|stopforceddisplaymath|stopextendcatcodetable|stopexpanded|stopdmath|stopctxfunctiondefinition|stopctxfunction|stopcontextdefinitioncode|stopcontextcode|stopcatcodetable|stop|startxmlsetups|starttexsetups|starttexdefinition|starttexcode|startsetups|startrawsetups|startpickupmath|startnointerference|startluasetups|startluaparameterset|startluacode|startlua|startlocalsetups|startimath|startforceddisplaymath|startextendcatcodetable|startexpanded|startdmath|startctxfunctiondefinition|startctxfunction|startcontextdefinitioncode|startcontextcode|startcatcodetable|start|space|sixthofsixarguments|sixthargumenttrue|sixthargumentfalse|singleexpandafter|simplegroupedcommand|signalcharacter|showluatokens|shiftbox|seventhargumenttrue|seventhargumentfalse|setxvalue|setxquantity|setxmeasure|setvalue|setuxvalue|setuvalue|setups|setup|setugvalue|setuevalue|settruevalue|settrue|setsystemmode|setstrut|setquantity|setprelistbox|setpostlistbox|setparagraphfreezing|setnewmacro|setnewconstant|setmode|setmeasure|setmathtextbox|setmathsmalltextbox|setlocalhsize|setgvalue|setgquantity|setgmeasure|setfalsevalue|setfalse|setexpandeddummyparameter|setevalue|setequantity|setemeasure|setdummyparameter|setcontrolspaces|setconstantvalue|setconstant|setconditional|setcatcodetable|setboxline|secondoftwounexpanded|secondoftwoarguments|secondofthreeunexpanded|secondofthreearguments|secondofsixarguments|secondoffourarguments|secondoffivearguments|secondargumenttrue|secondargumentfalse|scratchyposition|scratchyoffset|scratchxposition|scratchxoffset|scratchwidth|scratchvsize|scratchvoffset|scratchunicode|scratchtotal|scratchtopskip|scratchtopoffset|scratchtokstwo|scratchtoksthree|scratchtokssix|scratchtoksone|scratchtoksfour|scratchtoksfive|scratchtoks|scratchskiptwo|scratchskipthree|scratchskipsix|scratchskipone|scratchskipfour|scratchskipfive|scratchskip|scratchrightskip|scratchrightoffset|scratchoffset|scratchny|scratchnx|scratchmy|scratchmx|scratchmuskiptwo|scratchmuskipthree|scratchmuskipsix|scratchmuskipone|scratchmuskipfour|scratchmuskipfive|scratchmuskip|scratchmin|scratchmax|scratchmacrotwo|scratchmacroone|scratchmacro|scratchleftskip|scratchleftoffset|scratchhsize|scratchhoffset|scratchheight|scratchdistance|scratchdimentwo|scratchdimenthree|scratchdimensix|scratchdimenone|scratchdimenfour|scratchdimenfive|scratchdimen|scratchdepth|scratchcountertwo|scratchcounterthree|scratchcountersix|scratchcounterone|scratchcounterfour|scratchcounterfive|scratchcounter|scratchconditiontwotrue|scratchconditiontwofalse|scratchconditiontrue|scratchconditiononetrue|scratchconditiononefalse|scratchconditionfalse|scratchboxtwo|scratchboxthree|scratchboxsix|scratchboxone|scratchboxfour|scratchboxfive|scratchbox|scratchbottomskip|scratchbottomoffset|scangivendimensions|ruledvtop|ruledvss|ruledvskip|ruledvpack|ruledvglue|ruledvfilneg|ruledvfillneg|ruledvfilll|ruledvfill|ruledvfil|ruledvcenter|ruledvbox|ruledtpack|ruledpenalty|ruledmskip|ruledmkern|ruledmbox|ruledkern|ruledhss|ruledhskip|ruledhpack|ruledhglue|ruledhfilneg|ruledhfillneg|ruledhfilll|ruledhfill|ruledhfil|ruledhbox|rtlvtop|rtlvbox|rtlhbox|righttoleftvtop|righttoleftvbox|righttolefthbox|righttoleft|rightboundary|reversevtop|reversevpack|reversevbox|reversetpack|reversehpack|reversehbox|restorecatcodes|resetvalue|resetsystemmode|resetsetups|resetmode|resetglobal|reseteverypar|resetctxscanner|reqno|removeunwantedspaces|removetoks|removepunctuation|removelastspace|relrelspacing|relpunctspacing|relordspacing|relopspacing|relopenspacing|relinnerspacing|relclosespacing|relbinspacing|registerctxluafile|redoglobal|redefine|recurselevel|recursedepth|readline|readfromterminal|read|quitprevcommalist|quitcondition|quitcommalist|quarterstrut|quantity|quantitied|quad|pushsystemmode|pushoverloadmode|pushmathstyle|pushcatcodetable|punctrelspacing|punctpunctspacing|punctordspacing|punctopspacing|punctopenspacing|punctinnerspacing|punctclosespacing|punctbinspacing|protect|processfirstactioninset|processcommalist|processcommacommand|processallactionsinset|processallactions|processaction|privatescratchtoks|privatescratchskip|privatescratchmuskip|privatescratchdimen|privatescratchcounter|privatescratchbox|prependtotoks|prependtoks|prelistcopy|prelistbox|postlistcopy|postlistbox|popsystemmode|popoverloadmode|popmathstyle|popcatcodetable|pickupgroupedcommand|permitspacesbetweengroups|pardir|ordrelspacing|ordpunctspacing|ordordspacing|ordopspacing|ordopenspacing|ordinnerspacing|ordclosespacing|ordbinspacing|oprelspacing|oppunctspacing|opordspacing|opopspacing|opopenspacing|opinnerspacing|openrelspacing|openpunctspacing|openout|openordspacing|openopspacing|openopenspacing|openinnerspacing|openin|openclosespacing|openbinspacing|opclosespacing|opbinspacing|onlypdfobjectcompression|onlynonbreakablespace|oninterlineskip|offinterlineskip|obeytabs|obeyspaces|obeypages|obeyluatokens|obeylualines|obeylines|obeyedtab|obeyedspace|obeyedpage|obeyedline|null|novalidassignment|nosuperscript|nosuperprescript|nosubsprecript|nosubscript|nospacing|nospace|normalvglue|normalvfillneg|normalvfilllneg|normalsuperscript|normalsubscript|normalstopimath|normalstopdmath|normalstartimath|normalstartdmath|normalspaces|normalspace|normalreqno|normalpdfcompression|normalnosuperscript|normalnosubscript|normalhglue|normalhfillneg|normalhfilllneg|noprotrusion|nopdfobjectcompression|nopdfcompression|noligaturing|nokerning|nointerlineskip|nohyphens|noheightstrut|nofarguments|noexpansion|nobreak|nexttoken|nextbox|next|newwrite|newtoks|newsystemmode|newskip|newsignal|newread|newmuskip|newmode|newmarks|newmacro|newlanguage|newinsert|newif|newhelp|newfraction|newfamily|newfam|newdimen|newcount|newconstant|newconditional|newcatcodetable|newbox|newattribute|nbsp|naturalvtop|naturalvpack|naturalvbox|naturaltpack|naturalspace|naturalhpack|naturalhbox|morehyphens|modulonumber|measured|measure|maximumpdfcompression|mathtext|mathstylevcenteredvbox|mathstylevcenteredhbox|mathstylevcenter|mathstylevbox|mathstyletrigger|mathstylehbox|mathstylefont|mathstyleface|mathstylecommand|mathsmallstylefont|mathsmallstyleface|mathpalette|mathortext|mathnothing|mathnolop|mathlimop|mathbox|mathalpha|luaversion|luasetup|luaparameterset|luaminorversion|luamajorversion|luaexpr|luaexpanded|luaconditional|luacode|ltrvtop|ltrvbox|ltrhbox|loggingall|localhsize|lineheight|linedir|letvalue|letgvalue|letdummyparameter|letcatcodecommand|letbackslashbreak|lesshyphens|lefttorightvtop|lefttorightvbox|lefttorighthbox|lefttoright|leftorrightvtop|leftorrightvbox|leftorrighthbox|leftorright|leftboundary|lateluacode|lastlinewidth|keepunwantedspaces|installprotectedctxscanner|installprotectedctxfunction|installctxscanner|installctxfunction|installcorenamespace|innerrelspacing|innerpunctspacing|innerordspacing|inneropspacing|inneropenspacing|innerinnerspacing|innerclosespacing|innerbinspacing|inlineordisplaymath|indisplaymath|ignorevalue|ignoretabs|ignoreparskip|ignorepages|ignorelines|ignoreeofs|ifscratchconditiontwo|ifscratchconditionone|ifscratchcondition|ifbitwiseand|htdp|hsizefraction|hpenalty|hpackedbox|hpackbox|hkern|hglue|hfillneg|hfilllneg|hfilll|halfstrut|halflinestrut|groupedcommandcs|groupedcommand|goodbreak|gobbletwooptionals|gobbletwoarguments|gobblethreeoptionals|gobblethreearguments|gobbletenarguments|gobblesixarguments|gobblesevenarguments|gobbleoneoptional|gobbleoneargument|gobbleninearguments|gobblefouroptionals|gobblefourarguments|gobblefiveoptionals|gobblefivearguments|gobbleeightarguments|globalsetsystemmode|globalsetmode|globalscratchtoks|globalscratchskip|globalscratchmuskip|globalscratchdimen|globalscratchcountertwo|globalscratchcounterthree|globalscratchcounterone|globalscratchcounter|globalscratchbox|globalresetsystemmode|globalresetmode|globallet|givenwidth|givenheight|givendepth|getxparameters|getvalue|getuvalue|getparameters|getgparameters|getfirstcharacter|geteparameters|getdummyparameters|futureletnexttoken|frule|freezequantity|freezeparagraphproperties|freezemeasure|fourthofsixarguments|fourthoffourarguments|fourthoffivearguments|fourthargumenttrue|fourthargumentfalse|foundtrue|foundfalse|forgetparameters|forgetparagraphfreezing|forgetall|forcestrutdepth|forcedisplaymath|flushnextbox|firstoftwounexpanded|firstoftwoarguments|firstofthreeunexpanded|firstofthreearguments|firstofsixarguments|firstofoneunexpanded|firstofoneargument|firstoffourarguments|firstoffivearguments|firstinset|firstargumenttrue|firstargumentfalse|finishpar|filledhboxy|filledhboxr|filledhboxm|filledhboxk|filledhboxg|filledhboxc|filledhboxb|fifthofsixarguments|fifthoffivearguments|fifthargumenttrue|fifthargumentfalse|fastsetup|fastloopindex|fastloopfinal|falsecondition|expelsedoif|expdoifnot|expdoifinsetelse|expdoifelseinset|expdoifelsecommon|expdoifcommonelse|expdoif|expanded|exitloop|executeifdefined|enspace|endstrut|endpar|endgraf|emspace|empty|dummyparameter|dowithnextboxcs|dowithnextboxcontentcs|dowithnextboxcontent|dowithnextbox|dowith|doubleexpandafter|dotriplegroupempty|dotripleempty|dotripleargument|dostepwiserecurse|dospacing|dosixtupleempty|dosixtupleargument|dosinglegroupempty|dosingleempty|dosingleargument|doseventupleempty|doseventupleargument|dorecurse|doquintuplegroupempty|doquintupleempty|doquintupleargument|doquadruplegroupempty|doquadrupleempty|doquadrupleargument|dontpermitspacesbetweengroups|dontleavehmode|dontcomplain|donothing|donetrue|donefalse|doloopovermatched|doloopovermatch|doloopoverlist|doloop|doifvaluesomething|doifvaluenothingelse|doifvaluenothing|doifvalue|doifundefinedelse|doifundefined|doiftextelse|doiftext|doifsomethingelse|doifsomething|doifsetupselse|doifsetups|doifnumberelse|doifnumber|doifnotvalue|doifnottext|doifnotsetups|doifnotnumber|doifnotinstring|doifnotinset|doifnothingelse|doifnothing|doifnotcommon|doifnotcommandhandler|doifnot|doifnextparenthesiselse|doifnextoptionalelse|doifnextoptionalcselse|doifnextcharelse|doifnextcharcselse|doifnextbgroupelse|doifnextbgroupcselse|doifinstringelse|doifinstring|doifinsetelse|doifinset|doiffirstcharelse|doiffastoptionalcheckelse|doiffastoptionalcheckcselse|doifelsevaluenothing|doifelsevalue|doifelseundefined|doifelsetext|doifelsesomething|doifelsesetups|doifelsenumber|doifelsenothing|doifelsenextparenthesis|doifelsenextoptionalcs|doifelsenextoptional|doifelsenextcharcs|doifelsenextchar|doifelsenextbgroupcs|doifelsenextbgroup|doifelseinstring|doifelseinset|doifelsefirstchar|doifelsefastoptionalcheckcs|doifelsefastoptionalcheck|doifelsedimension|doifelsedefined|doifelsecommon|doifelsecommandhandler|doifelseassignmentcs|doifelseassignment|doifelse|doifdimensionelse|doifdefinedelse|doifdefined|doifcommonelse|doifcommon|doifcommandhandlerelse|doifcommandhandler|doifassignmentelsecs|doifassignmentelse|doif|dohyphens|doglobal|dofastloopcs|dodoublegroupempty|dodoubleempty|dodoubleargument|dodoglobal|docheckassignment|dividenumber|distributedhsize|dirrlo|dirrle|dirlro|dirlre|directsetup|directquantity|directmeasure|directluacode|directdummyparameter|depthstrut|defrostparagraphproperties|definequantity|definenamedlua|definemeasure|defineexpandable|define|defcatcodecommand|defbackslashbreak|defaultcatcodetable|currentcatcodetable|ctxwrite|ctxsprint|ctxreport|ctxluamatch|ctxluacode|ctxlua|ctxloadluafile|ctxlatelua|ctxlatecommand|ctxfunction|ctxdirectlua|ctxdirectcommand|ctxcommand|crlf|cramped|copysetups|copyparameters|copyboxline|controlspace|compoundhyphenpenalty|compounddiscretionary|closerelspacing|closepunctspacing|closeout|closeordspacing|closeopspacing|closeopenspacing|closeinnerspacing|closein|closeclosespacing|closebinspacing|cldprocessfile|cldloadviafile|cldloadfile|cldcontext|cldcommand|checkedstrippedcsname|checkedrighttoleft|checkedlefttoright|checked|charspace|catcodetablename|carryoverpar|break|boxrangewd|boxrangeht|boxrangedp|boxlinewd|boxlines|boxliners|boxlinerp|boxlinerh|boxlinenw|boxlinenh|boxlinend|boxlinels|boxlinelp|boxlinelh|boxlinein|boxlineht|boxlinedp|boxline|boxisempty|boxdir|booleanmodevalue|bitwisexor|bitwiseshift|bitwiseset|bitwiseor|bitwisenot|bitwisenil|bitwiseflip|bitwiseand|bitwise|binrelspacing|binpunctspacing|binordspacing|binopspacing|binopenspacing|bininnerspacing|binclosespacing|binbinspacing|begstrut|begcsname|availablehsize|autorule|autodirvtop|autodirvbox|autodirhbox|assumelongusagecs|appendtotoks|appendtoks|allowbreak|aliasmacro|Umathtopaccent|Umathbotaccent|Ucheckedstopdisplaymath|Ucheckedstartdisplaymath)(?=[^a-zA-Z])",
+   "match" : "\u005C\u005C(xmlsetup|writestatus|write|wait|vpenalty|vpackedbox|vpackbox|vkern|vglue|vfillneg|vfilllneg|vfilll|validassignment|uxdef|usedummystyleparameter|usedummystyleandcolor|usedummycolorparameter|usedlineskiplimit|usedlineskip|usedbaselineskip|updateparagraphshapes|updateparagraphproperties|updateparagraphpenalties|updateparagraphlines|updateparagraphdemerits|unvoidbox|unsupportedcs|unprotect|unique|unexpanded|undefinevalue|uncramped|ugdef|uedef|uedcatcodecommand|udef|twodigits|truecondition|tripleexpandafter|triggeruncrampedstyle|triggeruncrampedsmallstyle|triggeruncrampedbigstyle|triggertextstyle|triggersmallstyle|triggerscriptstyle|triggerscriptscriptstyle|triggermathstyle|triggergroupedcommandcs|triggergroupedcommand|triggerdisplaystyle|triggercrampedstyle|triggercrampedsmallstyle|triggercrampedbigstyle|triggerbigstyle|tracingnone|tracingall|to|threedigits|thirdofthreeunexpanded|thirdofthreearguments|thirdofsixarguments|thirdoffourarguments|thirdoffivearguments|thirdargumenttrue|thirdargumentfalse|then|thebox|textdir|texsetup|texdefinition|synchronizelayoutdirection|synchronizeinlinedirection|synchronizedisplaydirection|superscript|superprescript|subscript|subprescript|strutwd|struthtdp|strutht|strutgap|strutdp|strutbox|strut|strippedcsname|stopxmlsetups|stoptexsetups|stoptexdefinition|stoptexcode|stopsetups|stoprawsetups|stoppickupmath|stopnointerference|stopluasetups|stopluaparameterset|stopluacode|stoplua|stoplocalsetups|stopimath|stopforceddisplaymath|stopextendcatcodetable|stopexpanded|stopdmath|stopctxfunctiondefinition|stopctxfunction|stopcontextdefinitioncode|stopcontextcode|stopcatcodetable|stop|startxmlsetups|starttexsetups|starttexdefinition|starttexcode|startsetups|startrawsetups|startpickupmath|startnointerference|startluasetups|startluaparameterset|startluacode|startlua|startlocalsetups|startimath|startforceddisplaymath|startextendcatcodetable|startexpanded|startdmath|startctxfunctiondefinition|startctxfunction|startcontextdefinitioncode|startcontextcode|startcatcodetable|start|space|sixthofsixarguments|sixthargumenttrue|sixthargumentfalse|singleexpandafter|simplegroupedcommand|signalcharacter|showluatokens|shiftbox|seventhargumenttrue|seventhargumentfalse|setxvalue|setxquantity|setxmeasure|setvalue|setuxvalue|setuvalue|setups|setup|setugvalue|setuevalue|settruevalue|settrue|setsystemmode|setstrut|setquantity|setprelistbox|setpostlistbox|setparagraphfreezing|setnewmacro|setnewconstant|setmode|setmeasure|setmathtextbox|setmathsmalltextbox|setlocalhsize|setgvalue|setgquantity|setgmeasure|setfalsevalue|setfalse|setexpandeddummyparameter|setevalue|setequantity|setemeasure|setdummyparameter|setcontrolspaces|setconstantvalue|setconstant|setconditional|setcatcodetable|setboxline|secondoftwounexpanded|secondoftwoarguments|secondofthreeunexpanded|secondofthreearguments|secondofsixarguments|secondoffourarguments|secondoffivearguments|secondargumenttrue|secondargumentfalse|scratchyposition|scratchyoffset|scratchxposition|scratchxoffset|scratchwidth|scratchvsize|scratchvoffset|scratchunicode|scratchtotal|scratchtopskip|scratchtopoffset|scratchtokstwo|scratchtoksthree|scratchtokssix|scratchtoksone|scratchtoksfour|scratchtoksfive|scratchtoks|scratchskiptwo|scratchskipthree|scratchskipsix|scratchskipone|scratchskipfour|scratchskipfive|scratchskip|scratchrightskip|scratchrightoffset|scratchoffset|scratchny|scratchnx|scratchmy|scratchmx|scratchmuskiptwo|scratchmuskipthree|scratchmuskipsix|scratchmuskipone|scratchmuskipfour|scratchmuskipfive|scratchmuskip|scratchmin|scratchmax|scratchmacrotwo|scratchmacroone|scratchmacro|scratchleftskip|scratchleftoffset|scratchhsize|scratchhoffset|scratchheight|scratchdistance|scratchdimentwo|scratchdimenthree|scratchdimensix|scratchdimenone|scratchdimenfour|scratchdimenfive|scratchdimen|scratchdepth|scratchcountertwo|scratchcounterthree|scratchcountersix|scratchcounterone|scratchcounterfour|scratchcounterfive|scratchcounter|scratchconditiontwotrue|scratchconditiontwofalse|scratchconditiontrue|scratchconditiononetrue|scratchconditiononefalse|scratchconditionfalse|scratchboxtwo|scratchboxthree|scratchboxsix|scratchboxone|scratchboxfour|scratchboxfive|scratchbox|scratchbottomskip|scratchbottomoffset|scangivendimensions|ruledvtop|ruledvss|ruledvskip|ruledvpack|ruledvglue|ruledvfilneg|ruledvfillneg|ruledvfilll|ruledvfill|ruledvfil|ruledvcenter|ruledvbox|ruledtpack|ruledpenalty|ruledmskip|ruledmkern|ruledmbox|ruledkern|ruledhss|ruledhskip|ruledhpack|ruledhglue|ruledhfilneg|ruledhfillneg|ruledhfilll|ruledhfill|ruledhfil|ruledhbox|rtlvtop|rtlvbox|rtlhbox|righttoleftvtop|righttoleftvbox|righttolefthbox|righttoleft|rightboundary|reversevtop|reversevpack|reversevbox|reversetpack|reversehpack|reversehbox|restorecatcodes|resetvalue|resetsystemmode|resetsetups|resetmode|resetglobal|reseteverypar|resetctxscanner|reqno|removeunwantedspaces|removetoks|removepunctuation|removelastspace|relrelspacing|relpunctspacing|relordspacing|relopspacing|relopenspacing|relinnerspacing|relclosespacing|relbinspacing|registerctxluafile|redoglobal|redefine|recurselevel|recursedepth|readline|readfromterminal|read|quitprevcommalist|quitcondition|quitcommalist|quarterstrut|quantity|quantitied|quad|pushsystemmode|pushoverloadmode|pushmathstyle|pushcatcodetable|punctrelspacing|punctpunctspacing|punctordspacing|punctopspacing|punctopenspacing|punctinnerspacing|punctclosespacing|punctbinspacing|protect|processfirstactioninset|processcommalist|processcommacommand|processallactionsinset|processallactions|processaction|privatescratchtoks|privatescratchskip|privatescratchmuskip|privatescratchdimen|privatescratchcounter|privatescratchbox|prependtotoks|prependtoks|prelistcopy|prelistbox|postlistcopy|postlistbox|popsystemmode|popoverloadmode|popmathstyle|popcatcodetable|pickupgroupedcommand|permitspacesbetweengroups|pardir|ordrelspacing|ordpunctspacing|ordordspacing|ordopspacing|ordopenspacing|ordinnerspacing|ordclosespacing|ordbinspacing|oprelspacing|oppunctspacing|opordspacing|opopspacing|opopenspacing|opinnerspacing|openrelspacing|openpunctspacing|openout|openordspacing|openopspacing|openopenspacing|openinnerspacing|openin|openclosespacing|openbinspacing|opclosespacing|opbinspacing|onlypdfobjectcompression|onlynonbreakablespace|oninterlineskip|offinterlineskip|obeytabs|obeyspaces|obeypages|obeyluatokens|obeylualines|obeylines|obeyedtab|obeyedspace|obeyedpage|obeyedline|null|novalidassignment|nosuperscript|nosuperprescript|nosubsprecript|nosubscript|nospacing|nospace|normalvglue|normalvfillneg|normalvfilllneg|normalsuperscript|normalsubscript|normalstopimath|normalstopdmath|normalstartimath|normalstartdmath|normalspaces|normalspace|normalreqno|normalpdfcompression|normalnosuperscript|normalnosubscript|normalhglue|normalhfillneg|normalhfilllneg|norightligaturing|norightkerning|noprotrusion|nopdfobjectcompression|nopdfcompression|noligaturing|noleftligaturing|noleftkerning|nokerning|nointerlineskip|nohyphens|noheightstrut|nofarguments|noexpansion|nobreak|nexttoken|nextbox|next|newwrite|newtoks|newsystemmode|newskip|newsignal|newread|newmuskip|newmode|newmarks|newmacro|newlanguage|newinsert|newif|newhelp|newfraction|newfamily|newfam|newdimen|newcount|newconstant|newconditional|newcatcodetable|newbox|newattribute|nbsp|naturalvtop|naturalvpack|naturalvbox|naturaltpack|naturalspace|naturalhpack|naturalhbox|morehyphens|modulonumber|measured|measure|maximumpdfcompression|mathtext|mathstylevcenteredvbox|mathstylevcenteredhbox|mathstylevcenter|mathstylevbox|mathstyletrigger|mathstylehbox|mathstylefont|mathstyleface|mathstylecommand|mathsmallstylefont|mathsmallstyleface|mathpalette|mathortext|mathnothing|mathnolop|mathlimop|mathbox|mathalpha|luaversion|luasetup|luaparameterset|luaminorversion|luamajorversion|luaexpr|luaexpanded|luaconditional|luacode|ltrvtop|ltrvbox|ltrhbox|loggingall|localhsize|lineheight|linedir|letvalue|letgvalue|letdummyparameter|letcatcodecommand|letbackslashbreak|lesshyphens|lefttorightvtop|lefttorightvbox|lefttorighthbox|lefttoright|leftorrightvtop|leftorrightvbox|leftorrighthbox|leftorright|leftboundary|lateluacode|lastlinewidth|keepunwantedspaces|installprotectedctxscanner|installprotectedctxfunction|installctxscanner|installctxfunction|installcorenamespace|innerrelspacing|innerpunctspacing|innerordspacing|inneropspacing|inneropenspacing|innerinnerspacing|innerclosespacing|innerbinspacing|inlineordisplaymath|indisplaymath|ignorevalue|ignoretabs|ignoreparskip|ignorepages|ignorelines|ignoreeofs|ifscratchconditiontwo|ifscratchconditionone|ifscratchcondition|ifbitwiseand|htdp|hsizefraction|hpenalty|hpackedbox|hpackbox|hkern|hglue|hfillneg|hfilllneg|hfilll|halfstrut|halflinestrut|groupedcommandcs|groupedcommand|goodbreak|gobbletwooptionals|gobbletwoarguments|gobblethreeoptionals|gobblethreearguments|gobbletenarguments|gobblesixarguments|gobblesevenarguments|gobbleoneoptional|gobbleoneargument|gobbleninearguments|gobblefouroptionals|gobblefourarguments|gobblefiveoptionals|gobblefivearguments|gobbleeightarguments|globalsetsystemmode|globalsetmode|globalscratchtoks|globalscratchskip|globalscratchmuskip|globalscratchdimen|globalscratchcountertwo|globalscratchcounterthree|globalscratchcounterone|globalscratchcounter|globalscratchbox|globalresetsystemmode|globalresetmode|globallet|givenwidth|givenheight|givendepth|getxparameters|getvalue|getuvalue|getparameters|getgparameters|getfirstcharacter|geteparameters|getdummyparameters|futureletnexttoken|frule|freezequantity|freezeparagraphproperties|freezemeasure|fourthofsixarguments|fourthoffourarguments|fourthoffivearguments|fourthargumenttrue|fourthargumentfalse|foundtrue|foundfalse|forgetparameters|forgetparagraphfreezing|forgetall|forcestrutdepth|forcedisplaymath|flushnextbox|firstoftwounexpanded|firstoftwoarguments|firstofthreeunexpanded|firstofthreearguments|firstofsixarguments|firstofoneunexpanded|firstofoneargument|firstoffourarguments|firstoffivearguments|firstinset|firstargumenttrue|firstargumentfalse|finishpar|filledhboxy|filledhboxr|filledhboxm|filledhboxk|filledhboxg|filledhboxc|filledhboxb|fifthofsixarguments|fifthoffivearguments|fifthargumenttrue|fifthargumentfalse|fastsetup|fastloopindex|fastloopfinal|falsecondition|expelsedoif|expdoifnot|expdoifinsetelse|expdoifelseinset|expdoifelsecommon|expdoifcommonelse|expdoif|expanded|exitloop|executeifdefined|enspace|endstrut|endpar|endgraf|emspace|empty|dummyparameter|dowithnextboxcs|dowithnextboxcontentcs|dowithnextboxcontent|dowithnextbox|dowith|doubleexpandafter|dotriplegroupempty|dotripleempty|dotripleargument|dostepwiserecurse|dospacing|dosixtupleempty|dosixtupleargument|dosinglegroupempty|dosingleempty|dosingleargument|doseventupleempty|doseventupleargument|dorecurse|doquintuplegroupempty|doquintupleempty|doquintupleargument|doquadruplegroupempty|doquadrupleempty|doquadrupleargument|dontpermitspacesbetweengroups|dontleavehmode|dontcomplain|donothing|donetrue|donefalse|doloopovermatched|doloopovermatch|doloopoverlist|doloop|doifvaluesomething|doifvaluenothingelse|doifvaluenothing|doifvalue|doifundefinedelse|doifundefined|doiftextelse|doiftext|doifsomethingelse|doifsomething|doifsetupselse|doifsetups|doifnumberelse|doifnumber|doifnotvalue|doifnottext|doifnotsetups|doifnotnumber|doifnotinstring|doifnotinset|doifnothingelse|doifnothing|doifnotcommon|doifnotcommandhandler|doifnot|doifnextparenthesiselse|doifnextoptionalelse|doifnextoptionalcselse|doifnextcharelse|doifnextcharcselse|doifnextbgroupelse|doifnextbgroupcselse|doifinstringelse|doifinstring|doifinsetelse|doifinset|doiffirstcharelse|doiffastoptionalcheckelse|doiffastoptionalcheckcselse|doifelsevaluenothing|doifelsevalue|doifelseundefined|doifelsetext|doifelsesomething|doifelsesetups|doifelsenumber|doifelsenothing|doifelsenextparenthesis|doifelsenextoptionalcs|doifelsenextoptional|doifelsenextcharcs|doifelsenextchar|doifelsenextbgroupcs|doifelsenextbgroup|doifelseinstring|doifelseinset|doifelsefirstchar|doifelsefastoptionalcheckcs|doifelsefastoptionalcheck|doifelsedimension|doifelsedefined|doifelsecommon|doifelsecommandhandler|doifelseassignmentcs|doifelseassignment|doifelse|doifdimensionelse|doifdefinedelse|doifdefined|doifcommonelse|doifcommon|doifcommandhandlerelse|doifcommandhandler|doifassignmentelsecs|doifassignmentelse|doif|dohyphens|doglobal|dofastloopcs|dodoublegroupempty|dodoubleempty|dodoubleargument|dodoglobal|docheckassignment|dividenumber|distributedhsize|dirrlo|dirrle|dirlro|dirlre|directsetup|directquantity|directmeasure|directluacode|directdummyparameter|depthstrut|defrostparagraphproperties|definequantity|definenamedlua|definemeasure|defineexpandable|define|defcatcodecommand|defbackslashbreak|defaultcatcodetable|currentcatcodetable|ctxwrite|ctxsprint|ctxreport|ctxluamatch|ctxluacode|ctxlua|ctxloadluafile|ctxlatelua|ctxlatecommand|ctxfunction|ctxdirectlua|ctxdirectcommand|ctxcommand|crlf|cramped|copysetups|copyparameters|copyboxline|controlspace|compoundhyphenpenalty|compounddiscretionary|closerelspacing|closepunctspacing|closeout|closeordspacing|closeopspacing|closeopenspacing|closeinnerspacing|closein|closeclosespacing|closebinspacing|cldprocessfile|cldloadviafile|cldloadfile|cldcontext|cldcommand|checkedstrippedcsname|checkedrighttoleft|checkedlefttoright|checked|charspace|catcodetablename|carryoverpar|break|boxrangewd|boxrangeht|boxrangedp|boxlinewd|boxlines|boxliners|boxlinerp|boxlinerh|boxlinenw|boxlinenh|boxlinend|boxlinels|boxlinelp|boxlinelh|boxlinein|boxlineht|boxlinedp|boxline|boxisempty|boxdir|booleanmodevalue|bitwisexor|bitwiseshift|bitwiseset|bitwiseor|bitwisenot|bitwisenil|bitwiseflip|bitwiseand|bitwise|binrelspacing|binpunctspacing|binordspacing|binopspacing|binopenspacing|bininnerspacing|binclosespacing|binbinspacing|begstrut|begcsname|availablehsize|autorule|autodirvtop|autodirvbox|autodirhbox|assumelongusagecs|appendtotoks|appendtoks|allowbreak|aliasmacro|Umathtopaccent|Umathbotaccent|Ucheckedstopdisplaymath|Ucheckedstartdisplaymath)(?=[^a-zA-Z])",
    "name" : "context.plain.commands.plain.tex"
   },
   "ifprimitive" : {
diff --git a/doc/context/documents/general/manuals/luametatex.pdf b/doc/context/documents/general/manuals/luametatex.pdf
index 5bd0800ce..52c93219f 100644
Binary files a/doc/context/documents/general/manuals/luametatex.pdf and b/doc/context/documents/general/manuals/luametatex.pdf differ
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index 99eb92a6d..65a661ac4 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -16,7 +16,7 @@ local lower = string.lower
 local concat = table.concat
 local write_nl = (logs and logs.writer) or (texio and texio.write_nl) or print
 
-local otlversion  = 3.112
+local otlversion  = 3.113
 
 local helpinfo = [[
 <?xml version="1.0"?>
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index a466ff87a..d4a5fdb76 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2021.01.05 10:41}
+\newcontextversion{2021.01.07 16:56}
 
 %D This file is loaded at runtime, thereby providing an
 %D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 063d2e462..1d1031281 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
 %D your styles an modules.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2021.01.05 10:41}
+\edef\contextversion{2021.01.07 16:56}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii
index 4c9092f89..d3a073db3 100644
--- a/tex/context/base/mkii/mult-en.mkii
+++ b/tex/context/base/mkii/mult-en.mkii
@@ -1131,6 +1131,7 @@
 \setinterfaceconstant{reference}{reference}
 \setinterfaceconstant{referencemethod}{referencemethod}
 \setinterfaceconstant{referenceprefix}{referenceprefix}
+\setinterfaceconstant{referencetext}{referencetext}
 \setinterfaceconstant{referencing}{referencing}
 \setinterfaceconstant{region}{region}
 \setinterfaceconstant{regionin}{regionin}
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index dff51fd71..cf07d5340 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
 
 % \normalend % uncomment this to get the real base runtime
 
-\newcontextversion{2021.01.05 10:41}
+\newcontextversion{2021.01.07 16:56}
 
 %D This file is loaded at runtime, thereby providing an excellent place for hacks,
 %D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 8e9dda9c3..10c8b1fdf 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2021.01.05 10:41}
+\edef\contextversion{2021.01.07 16:56}
 
 %D Kind of special:
 
diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua
index b7d45392d..4e2981011 100644
--- a/tex/context/base/mkiv/font-cff.lua
+++ b/tex/context/base/mkiv/font-cff.lua
@@ -1425,13 +1425,15 @@ do
     -- to wrap my head around the rather complex variable font specification
     -- with regions and axis, the following approach kind of works but is more
     -- some trial and error trick. It's still not clear how much of the complex
-    -- truetype description applies to cff.
+    -- truetype description applies to cff. Once there are fonts out there we'll
+    -- get there. (Marcel and friends did some tests with recent cff2 fonts so
+    -- the code has been adapted accordingly.)
 
     local reginit = false
 
     local function updateregions(n) -- n + 1
         if regions then
-            local current = regions[n] or regions[1]
+            local current = regions[n+1] or regions[1]
             nofregions = #current
             if axis and n ~= reginit then
                 factors = { }
@@ -2155,7 +2157,14 @@ do
         popped   = 3
         seacs    = { }
         if regions then
-            regions = { regions } -- needs checking
+            -- this was:
+         -- regions = { regions } -- needs checking
+            -- and is now (MFC):
+            regions = { }
+            local deltas = data.deltas
+            for i = 1, #deltas do
+                regions[i] = deltas[i].regions
+            end
             axis = data.factors or false
         end
     end
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index 91ee83b19..8d7c3d359 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -503,7 +503,7 @@ local function readvariationdata(f,storeoffset,factors) -- store
         regions[i] = t
     end
     -- deltas
-    if factors then
+ -- if factors then
         for i=1,nofdeltadata do
             setposition(f,storeoffset+deltadata[i])
             local nofdeltasets = readushort(f)
@@ -528,7 +528,7 @@ local function readvariationdata(f,storeoffset,factors) -- store
                 scales  = factors and getscales(usedregions,factors) or nil,
             }
         end
-    end
+ -- end
     setposition(f,position)
     return regions, deltadata
 end
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index da22f3bf9..18120f524 100644
--- a/tex/context/base/mkiv/font-mis.lua
+++ b/tex/context/base/mkiv/font-mis.lua
@@ -21,7 +21,7 @@ local readers  = otf.readers
 
 if readers then
 
-    otf.version = otf.version or 3.112
+    otf.version = otf.version or 3.113
     otf.cache   = otf.cache   or containers.define("fonts", "otl", otf.version, true)
 
     function fonts.helpers.getfeatures(name,save)
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index b8e13f107..19de2bb77 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -52,7 +52,7 @@ local report_otf          = logs.reporter("fonts","otf loading")
 local fonts               = fonts
 local otf                 = fonts.handlers.otf
 
-otf.version               = 3.112 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version               = 3.113 -- beware: also sync font-mis.lua and in mtx-fonts
 otf.cache                 = containers.define("fonts", "otl", otf.version, true)
 otf.svgcache              = containers.define("fonts", "svg", otf.version, true)
 otf.pngcache              = containers.define("fonts", "png", otf.version, true)
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index 1f4806ee2..880bcb6d5 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -829,6 +829,9 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
         -- of{f-}{}{f}e  o{f-}{}{f}fe  o{-}{}{ff}e (oe and ff ligature)
         -- we can end up here when we have a start run .. testruns start at a disc but
         -- so here we have the other case: char + disc
+        --
+        -- Challenge for Kai (latinmodern):  \hyphenation{fii-f-f-iif} fiiffiif
+        --
         if discfound then
             -- don't assume marks in a disc and we don't run over a disc (for now)
             local pre, post, replace = getdisc(discfound)
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index fb786231e..2b1dffc68 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -541,7 +541,8 @@ return {
         "prelistbox", "postlistbox", "prelistcopy", "postlistcopy", "setprelistbox", "setpostlistbox",
         --
         "noligaturing", "nokerning", "noexpansion", "noprotrusion",
-        --
+        "noleftkerning", "noleftligaturing", "norightkerning", "norightligaturing",
+         --
         "futureletnexttoken", "defbackslashbreak", "letbackslashbreak",
         --
         "pushoverloadmode", "popoverloadmode",
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 6f1f7acfe..154b18975 100644
Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 2e51acc39..9434bf9cd 100644
Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ
diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua
index 323ad4dc9..c06e32df3 100644
--- a/tex/context/base/mkiv/task-ini.lua
+++ b/tex/context/base/mkiv/task-ini.lua
@@ -53,6 +53,7 @@ appendaction("processors",   "fonts",       "typesetters.fontkerns.handler",
 appendaction("processors",   "fonts",       "nodes.handlers.protectglyphs",                     nil, "nonut",  "enabled"   )
 appendaction("processors",   "fonts",       "builders.kernel.ligaturing",                       nil, "nut",    "disabled"  )
 appendaction("processors",   "fonts",       "builders.kernel.kerning",                          nil, "nut",    "disabled"  )
+appendaction("processors",   "fonts",       "nodes.handlers.show",                              nil, "nut",    "disabled"  )
 appendaction("processors",   "fonts",       "nodes.handlers.stripping",                         nil, "nut",    "disabled"  )
 appendaction("processors",   "fonts",       "nodes.handlers.flatten",                           nil, "nut",    "disabled"  )
 appendaction("processors",   "fonts",       "fonts.goodies.colorschemes.coloring",              nil, "nut",    "disabled"  )
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 0fae7c684..700283051 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
 
 % \normalend % uncomment this to get the real base runtime
 
-\newcontextversion{2021.01.05 10:41}
+\newcontextversion{2021.01.07 16:56}
 
 %D This file is loaded at runtime, thereby providing an excellent place for hacks,
 %D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index 8c6701d81..1a20d3a85 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2021.01.05 10:41}
+\immutable\edef\contextversion{2021.01.07 16:56}
 
 %overloadmode 1 % check frozen / warning
 %overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt
index 7a0ccf25b..57ac9e294 100644
--- a/tex/context/base/mkxl/driv-shp.lmt
+++ b/tex/context/base/mkxl/driv-shp.lmt
@@ -925,8 +925,9 @@ local hlist_out, vlist_out  do
                 end
             elseif id == disc_code then
                 local replace, tail = getreplace(current)
-                if replace and subtype ~= select_disc then
-                    -- we could flatten .. no gain
+                -- actually, we no longer have these select discs in the packaged list ... it's about
+                -- time to clean up the disc code a bit further
+                if replace then -- and subtype ~= select_disc_code then
                     setlink(tail,getnext(current))
                     setlink(current,replace)
                     setreplace(current)
diff --git a/tex/context/base/mkxl/font-col.lmt b/tex/context/base/mkxl/font-col.lmt
index a0e40d0ba..200551099 100644
--- a/tex/context/base/mkxl/font-col.lmt
+++ b/tex/context/base/mkxl/font-col.lmt
@@ -24,6 +24,8 @@ local setfont            = nuts.setfont
 
 ----- traverse_char      = nuts.traverse_char
 local nextchar           = nuts.traversers.char
+local getscales          = nuts.getscales
+local setscales          = nuts.setscales
 
 local settings_to_hash   = utilities.parsers.settings_to_hash
 
@@ -230,9 +232,15 @@ function collections.clonevector(name)
         local oldchars   = fontdata[current].characters
         local newchars   = fontdata[cloneid].characters
         local factor     = definition.factor
+        local rscale     = definition.rscale
         if factor then
             vector.factor = factor
         end
+if tex.conditionals["c_font_compact"] then
+        if rscale then
+            vector.rscale = rscale
+        end
+end
         if trace_collecting then
             if target then
                 report_fonts("remapping font %a to %a for range %U - %U, offset %X, target %U",current,cloneid,start,stop,offset,target)
@@ -334,6 +342,9 @@ function collections.prepare(name) -- we can do this in lua now .. todo
             local f = d[i]
             local name = f.font
             local scale = f.rscale or 1
+if tex.conditionals["c_font_compact"] then
+    scale = 1
+end
             if fontpatternhassize(name) then
                 context.font_fallbacks_clone_unique(name,scale)
             else
@@ -393,26 +404,33 @@ function collections.process(head) -- this way we keep feature processing
             local vect = vector[char]
             if not vect then
                 -- keep it
-            elseif type(vect) == "table" then
-                local newfont = vect[1]
-                local newchar = vect[2]
-                if trace_collecting then
-                    report_fonts("remapping character %C in font %a to character %C in font %a%s",
-                        char,font,newchar,newfont,not chardata[newfont][newchar] and " (missing)" or ""
-                    )
-                end
-                setfont(n,newfont,newchar)
             else
-                local fakemono = vector.factor
-                if trace_collecting then
-                    report_fonts("remapping font %a to %a for character %C%s",
-                        font,vect,char,not chardata[vect][char] and " (missing)" or ""
-                    )
-                end
-                if fakemono then
-                    setfont(n,vect,monoslot(vect,char,font,fakemono))
+                if type(vect) == "table" then
+                    local newfont = vect[1]
+                    local newchar = vect[2]
+                    if trace_collecting then
+                        report_fonts("remapping character %C in font %a to character %C in font %a%s",
+                            char,font,newchar,newfont,not chardata[newfont][newchar] and " (missing)" or ""
+                        )
+                    end
+                    setfont(n,newfont,newchar)
                 else
-                    setfont(n,vect)
+                    local fakemono = vector.factor
+                    if trace_collecting then
+                        report_fonts("remapping font %a to %a for character %C%s",
+                            font,vect,char,not chardata[vect][char] and " (missing)" or ""
+                        )
+                    end
+                    if fakemono then
+                        setfont(n,vect,monoslot(vect,char,font,fakemono))
+                    else
+                        setfont(n,vect)
+                    end
+                end
+                local rscale = vector.rscale
+                if rscale and rscale ~= 1 then
+                    local s, x, y = getscales(n)
+                    setscales(n,s*rscale,x*rscale,y*rscale)
                 end
             end
         end
diff --git a/tex/context/base/mkxl/font-ctx.lmt b/tex/context/base/mkxl/font-ctx.lmt
index b316bcc0a..c59f4c9e7 100644
--- a/tex/context/base/mkxl/font-ctx.lmt
+++ b/tex/context/base/mkxl/font-ctx.lmt
@@ -1166,8 +1166,13 @@ do  -- else too many locals
     implement {
         name      = "definefont_two",
         arguments = {
-            "boolean", "string", "string", "integer", "integer", "string", "string", "string", "string",
-            "integer", "integer", "integer", "string", "string", "string", "string", "integer",
+         -- "boolean", "string", "string", "dimension", "integer", "string",
+         -- "string", "string", "string", "integer", "dimension", "string",
+         -- "string", "string", "string", "integer",
+            "boolean", "argument", "argument", "dimension", "integer",
+            "argument", "argument", "argument", "argument", "integer",
+            "dimension", "argument", "argument", "argument", "argument",
+            "integer",
         },
         actions   = function (
                         global,          -- \ifx\fontclass\empty\s!false\else\s!true\fi
@@ -1181,7 +1186,6 @@ do  -- else too many locals
                         fontfallbacks,   -- \m_font_fallbacks
                         mathsize,        -- \fontface
                         textsize,        -- \d_font_scaled_text_face
-                        relativeid,      -- \relativefontid
                         classgoodies,    -- \m_font_class_goodies
                         goodies,         -- \m_font_goodies
                         classdesignsize, -- \m_font_class_designsize
diff --git a/tex/context/base/mkxl/font-ini.mklx b/tex/context/base/mkxl/font-ini.mklx
index bb5050527..ea049bc38 100644
--- a/tex/context/base/mkxl/font-ini.mklx
+++ b/tex/context/base/mkxl/font-ini.mklx
@@ -495,8 +495,6 @@
    \ifx\p_font_rscale\v!auto
      \let\p_font_rscale\plusone
      \font_helpers_check_relative_font_id
-   \else
-     \let\relativefontid\minusone
    \fi}
 
 \def\font_rscale_xx#style%
@@ -668,8 +666,6 @@
 \newcount\lastfontid      % also used at the lua end / tex end
 \newtoks \everydefinefont
 
-\mutable\let\relativefontid\minusone
-
 \aliased\let\c_font_feature_inheritance_fontnone  \zerocount  % none
 \aliased\let\c_font_feature_inheritance_fontonly  \plusone    % fontonly
 \aliased\let\c_font_feature_inheritance_classonly \plustwo    % classonly
@@ -771,23 +767,39 @@
    \font_helpers_update_font_parameters
    \font_helpers_update_font_class_parameters
   %\writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}%
+%    \clf_definefont_two
+%       \ifempty\fontclass\s!false\else\s!true\fi
+%       {#csname}%
+%       {\somefontfile}%
+%       \d_font_scaled_font_size
+%       \c_font_feature_inheritance_mode
+%       {\m_font_class_features}%
+%       {\m_font_features}%
+%       {\m_font_class_fallbacks}%
+%       {\m_font_fallbacks}%
+%       \fontface
+%       \d_font_scaled_text_face
+%       {\m_font_class_goodies}%
+%       {\m_font_goodies}%
+%       {\m_font_class_designsize}%
+%       {\m_font_designsize}%
+%       \scaledfontmode
    \clf_definefont_two
       \ifempty\fontclass\s!false\else\s!true\fi
       {#csname}%
-      {\somefontfile}%
+      \somefontfile
       \d_font_scaled_font_size
       \c_font_feature_inheritance_mode
-      {\m_font_class_features}%
-      {\m_font_features}%
-      {\m_font_class_fallbacks}%
-      {\m_font_fallbacks}%
+      \m_font_class_features
+      \m_font_features
+      \m_font_class_fallbacks
+      \m_font_fallbacks
       \fontface
       \d_font_scaled_text_face
-      \relativefontid
-      {\m_font_class_goodies}%
-      {\m_font_goodies}%
-      {\m_font_class_designsize}%
-      {\m_font_designsize}%
+      \m_font_class_goodies
+      \m_font_goodies
+      \m_font_class_designsize
+      \m_font_designsize
       \scaledfontmode
    \relax
    \ifcase\scaledfontsize
@@ -880,23 +892,39 @@
    \font_helpers_update_font_class_parameters
    % ... till here
   %\writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}%
+%    \clf_definefont_two
+%       \ifempty\fontclass\s!false\else\s!true\fi
+%       {#csname}%
+%       {\somefontfile}%
+%       \d_font_scaled_font_size
+%       \c_font_feature_inheritance_mode
+%       {\m_font_class_features}%
+%       {\m_font_features}%
+%       {\m_font_class_fallbacks}%
+%       {\m_font_fallbacks}%
+%       \fontface
+%       \d_font_scaled_text_face
+%       {\m_font_class_goodies}%
+%       {\m_font_goodies}%
+%       {\m_font_class_designsize}%
+%       {\m_font_designsize}%
+%       \scaledfontmode
    \clf_definefont_two
       \ifempty\fontclass\s!false\else\s!true\fi
       {#csname}%
-      {\somefontfile}%
+      \somefontfile
       \d_font_scaled_font_size
       \c_font_feature_inheritance_mode
-      {\m_font_class_features}%
-      {\m_font_features}%
-      {\m_font_class_fallbacks}%
-      {\m_font_fallbacks}%
+      \m_font_class_features
+      \m_font_features
+      \m_font_class_fallbacks
+      \m_font_fallbacks
       \fontface
       \d_font_scaled_text_face
-      \relativefontid
-      {\m_font_class_goodies}%
-      {\m_font_goodies}%
-      {\m_font_class_designsize}%
-      {\m_font_designsize}%
+      \m_font_class_goodies
+      \m_font_goodies
+      \m_font_class_designsize
+      \m_font_designsize
       \scaledfontmode
    \relax
    \ifcase\scaledfontsize
@@ -907,15 +935,15 @@
    \else
      \edef\somefontspec{at \number\scaledfontsize sp}% we need the resolved designsize (for fallbacks)
      %
-     \ifnum\c_font_scaled_font_mode_saved>\plusfour
-       \glyphscale\numexpr\plusthousand*\dimexpr\d_font_scaled_font_size\relax/\c_font_scaled_points\relax
-     \else
-       \glyphscale\c_font_future_glyph_scale
-     \fi
-     % actually this has to happen elsewhere .. temp hack (do we know here if we are global?)
-     \gletcsname\??frozenfont#csname\expandafter\endcsname\csname#csname\endcsname
-     \protected\xdefcsname#csname\endcsname
-       {\csname\??frozenfont#csname\endcsname
+     \glyphscale
+       \ifnum\c_font_scaled_font_mode_saved>\plusfour
+         \numexpr\plusthousand*\dimexpr\d_font_scaled_font_size\relax/\c_font_scaled_points\relax
+       \else
+         \c_font_future_glyph_scale
+       \fi
+     \ifempty\fontclass\else\global\fi
+     \protected\edefcsname#csname\endcsname
+       {\setfontid\the\fontid\csname#csname\endcsname\relax
         \glyphscale\the\glyphscale\relax}%
      %
      \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname
@@ -1051,28 +1079,14 @@
 %D Beware, in the frozen variants no settings are supported yet, but that might happen
 %D some day.
 
-\installcorenamespace{frozenfont}
-%installcorenamespace{frozensize}
-
-\newcount\c_last_global_glyph_scale
-
 \permanent\tolerant\protected\def\definefrozenfont[#name]#spacer[#specification]#spacer[#settings]%
   {\ifparameter#name\or
      \begingroup
        \definefont[#name][#specification][#settings]%
        \csname#name\endcsname
        \glet\lastglobalrawfontcall\lastrawfontcall
-       \global\c_last_global_glyph_scale\glyphscale
      \endgroup
-     \ifconditional\c_font_compact
-       % temp hack
-       \letcsname\??frozenfont#name\endcsname\lastglobalrawfontcall
-       \protected\edefcsname#name\endcsname
-         {\csname\??frozenfont#name\endcsname
-          \glyphscale\the\c_last_global_glyph_scale\relax}%
-     \else
-       \letcsname#name\endcsname\lastglobalrawfontcall
-     \fi
+     \letcsname#name\endcsname\lastglobalrawfontcall
    \fi}
 
 %D The instance namespace protection makes the switch local so that we can redefine a
diff --git a/tex/context/base/mkxl/font-mat.mklx b/tex/context/base/mkxl/font-mat.mklx
index 0e3b3fbad..561effd58 100644
--- a/tex/context/base/mkxl/font-mat.mklx
+++ b/tex/context/base/mkxl/font-mat.mklx
@@ -253,34 +253,67 @@
 %D little in restoring global states and, what's more important, we get rid of large
 %D math parameter push/pop in tracingall when not needed.
 
-\def\font_helpers_preset_math_family_indeed#fam#familytag%
-  {\expandafter\let\expandafter\v_font_math_one\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname
-   \ifrelax\v_font_math_one
-     \font_helpers_preset_math_family_warning
-   \orelse\ifnum\fontid\textfont#fam=\fontid\v_font_math_one\else
-     \font_helpers_preset_math_family_indeed_changed#fam#familytag%
+% \def\font_helpers_preset_math_family_indeed#fam#familytag%
+%   {\expandafter\let\expandafter\v_font_math_one\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname
+%    \ifrelax\v_font_math_one
+%      \font_helpers_preset_math_family_warning
+%    \orelse\ifnum\fontid\textfont#fam=\fontid\v_font_math_one\else
+%      \font_helpers_preset_math_family_indeed_changed#fam#familytag%
+%    \fi}
+
+% \def\font_helpers_preset_math_family_warning
+%   {\writestatus{fonts}{math: unset for global bodyfont \fontclass\space at \fontbody}}
+
+% \def\font_helpers_preset_math_family_indeed_changed_normal#fam#familytag%
+%   {\font_helpers_set_math_family_set_scales_normal
+%    \scriptscriptfont#fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-3\endcsname
+%    \scriptfont      #fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-2\endcsname
+%    \textfont        #fam\v_font_math_one}
+
+% \def\font_helpers_preset_math_family_indeed_changed_compact#fam#familytag%
+%   {\font_helpers_set_math_family_set_scales_compact
+%    \scriptscriptfont#fam\v_font_math_one
+%    \scriptfont      #fam\v_font_math_one
+%    \textfont        #fam\v_font_math_one}
+
+% \def\font_helpers_preset_math_family_indeed_changed
+%   {\ifconditional\c_font_compact
+%      \expandafter\font_helpers_preset_math_family_indeed_changed_compact
+%    \else
+%      \expandafter\font_helpers_preset_math_family_indeed_changed_normal
+%    \fi}
+
+\def\font_helpers_preset_math_family_indeed_normal#fam#familytag%
+  {\expandafter\let\expandafter\font_math_last_font\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname
+   \font_math_last_font
+   \ifnum\fontid\textfont#fam=\fontid\font\else
+     \font_helpers_preset_math_family_indeed_changed_normal#fam#familytag%
    \fi}
 
-\def\font_helpers_preset_math_family_warning
-  {\writestatus{fonts}{math: unset for global bodyfont \fontclass\space at \fontbody}}
-
 \def\font_helpers_preset_math_family_indeed_changed_normal#fam#familytag%
   {\font_helpers_set_math_family_set_scales_normal
-   \scriptscriptfont#fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-3\endcsname
-   \scriptfont      #fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-2\endcsname
-   \textfont        #fam\v_font_math_one}
+   \csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-3\endcsname\scriptscriptfont#fam\font
+   \csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-2\endcsname\scriptfont      #fam\font
+ % \csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname\textfont        #fam\font}
+   \font_math_last_font                                                                  \textfont        #fam\font}
+
+\def\font_helpers_preset_math_family_indeed_compact#fam#familytag%
+  {\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname
+   \ifnum\fontid\textfont#fam=\fontid\font\else
+     \font_helpers_preset_math_family_indeed_changed_compact#fam%
+   \fi}
 
-\def\font_helpers_preset_math_family_indeed_changed_compact#fam#familytag%
+\def\font_helpers_preset_math_family_indeed_changed_compact#fam%
   {\font_helpers_set_math_family_set_scales_compact
-   \scriptscriptfont#fam\v_font_math_one
-   \scriptfont      #fam\v_font_math_one
-   \textfont        #fam\v_font_math_one}
+   \scriptscriptfont#fam\font
+   \scriptfont      #fam\font
+   \textfont        #fam\font}
 
-\def\font_helpers_preset_math_family_indeed_changed
+\def\font_helpers_preset_math_family_indeed
   {\ifconditional\c_font_compact
-     \expandafter\font_helpers_preset_math_family_indeed_changed_compact
+     \expandafter\font_helpers_preset_math_family_indeed_compact
    \else
-     \expandafter\font_helpers_preset_math_family_indeed_changed_normal
+     \expandafter\font_helpers_preset_math_family_indeed_normal
    \fi}
 
 \let\font_helpers_reset_fontclass_math_families\gobbleoneargument
diff --git a/tex/context/base/mkxl/font-ots.lmt b/tex/context/base/mkxl/font-ots.lmt
index 03e0f47fa..578e661eb 100644
--- a/tex/context/base/mkxl/font-ots.lmt
+++ b/tex/context/base/mkxl/font-ots.lmt
@@ -133,7 +133,6 @@ local registertracker      = trackers.register
 local logs                 = logs
 local trackers             = trackers
 local nodes                = nodes
-local attributes           = attributes
 local fonts                = fonts
 
 local otf                  = fonts.handlers.otf
@@ -194,7 +193,6 @@ local getboth            = nuts.getboth
 local setboth            = nuts.setboth
 local getid              = nuts.getid
 local getstate           = nuts.getstate
-local getsubtype         = nuts.getsubtype
 local setsubtype         = nuts.setsubtype
 local getchar            = nuts.getchar
 local setchar            = nuts.setchar
@@ -203,9 +201,11 @@ local setdisc            = nuts.setdisc
 local getreplace         = nuts.getreplace
 local setlink            = nuts.setlink
 local getwidth           = nuts.getwidth
+local getoptions         = nuts.getoptions
+local setoptions         = nuts.setoptions
 
 local getglyphdata       = nuts.getglyphdata
-local getwhatever        = nuts.getwhatever
+local getscales          = nuts.getscales
 
 ---------------------------------------------------------------------------------------
 
@@ -247,7 +247,6 @@ local nextnode           = nuts.traversers.node
 
 local nodecodes          = nodes.nodecodes
 local glyphcodes         = nodes.glyphcodes
-local disccodes          = nodes.disccodes
 
 local glyph_code         = nodecodes.glyph
 local glue_code          = nodecodes.glue
@@ -259,7 +258,7 @@ local par_code           = nodecodes.par
 local lefttoright_code   = nodes.dirvalues.lefttoright
 local righttoleft_code   = nodes.dirvalues.righttoleft
 
-local discretionarydisc_code = disccodes.discretionary
+local discretionarydisc_code = nodes.disccodes.discretionary
 local ligatureglyph_code     = glyphcodes.ligature
 
 local injections         = nodes.injections
@@ -294,7 +293,7 @@ local descriptions       = false
 local marks              = false
 local classes            = false
 local currentfont        = false
-local currentattr        = false
+local currentdynamic     = false
 local currentscale       = false
 local currentxscale      = false
 local currentyscale      = false
@@ -517,15 +516,37 @@ local has_glyph_option       = nuts.has_glyph_option
 
 -- in lmtx we need to check the components and can be slightly more clever
 
-local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head
-    if has_glyph_option(start,no_right_ligature_code) then
-        return head, start
+local function inhibited(start,stop)
+    for n in nextnode, start do
+        -- we asume glyph nodes
+        if n == start then
+            if has_glyph_option(n,no_right_ligature_code) then
+                return true
+            end
+        elseif n == stop then
+            if has_glyph_option(n,no_left_ligature_code) then
+                return true
+            else
+                return false
+            end
+        elseif has_glyph_option(n,no_left_ligature_code) then
+            return true
+        elseif has_glyph_option(n,no_right_ligature_code) then
+            return true
+        end
     end
+    return false
+end
+
+local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head
     if start == stop and getchar(start) == char then
         resetinjection(start)
         setchar(start,char)
         return head, start
     end
+    if inhibited(start,stop) then
+        return head, start
+    end
     local prev = getprev(start)
     local next = getnext(stop)
     local comp = start
@@ -537,6 +558,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
     end
     resetinjection(base)
     setchar(base,char)
+    setoptions(base,getoptions(start) | getoptions(stop)) -- maybe only lig options
     setsubtype(base,ligatureglyph_code)
     set_components(base,comp)
     setlink(prev,base,next)
@@ -572,7 +594,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
         -- we can have one accent as part of a lookup and another following
         local start = getnext(current)
         while start do
-            local char = ischar(start)
+            local nxt, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if char then
                 -- also something skiphash here?
                 if marks[char] then
@@ -580,7 +602,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
                     if trace_marks then
                         logwarning("%s: set ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
                     end
-                    start = getnext(start)
+                    start = nxt
                 else
                     break
                 end
@@ -756,7 +778,7 @@ end
 -- marks that are kept.
 
 function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash)
-    local current   = getnext(start)
+    local current = getnext(start)
     if not current then
         return head, start, false, nil
     end
@@ -764,7 +786,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
     local startchar = getchar(start)
     if skiphash and skiphash[startchar] then
         while current do
-            local nxt, char = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale)
+            local nxt, char = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if char then
                 local lg = ligature[char]
                 if lg then
@@ -798,7 +820,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
         local discfound = false
         local hasmarks  = marks[startchar]
         while current do
-            local nxt, char, id = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale)
+            local nxt, char, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if char then
                 if skiphash and skiphash[char] then
                     current = nxt
@@ -828,25 +850,27 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
         -- of{f-}{}{f}e  o{f-}{}{f}fe  o{-}{}{ff}e (oe and ff ligature)
         -- we can end up here when we have a start run .. testruns start at a disc but
         -- so here we have the other case: char + disc
+        --
+        -- Challenge for Kai (latinmodern):  \hyphenation{fii-f-f-iif} fiiffiif
+        --
         if discfound then
             -- don't assume marks in a disc and we don't run over a disc (for now)
             local pre, post, replace = getdisc(discfound)
             local match
             if replace then
-                local char = ischar(replace,currentfont,currentscale,currentxscale,currentyscale)
+                local nxt, char = isnextchar(replace,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                 if char and ligature[char] then
                     match = true
                 end
             end
             if not match and pre then
-                local char = ischar(pre,currentfont,currentscale,currentxscale,currentyscale)
+                local nxt, char = isnextchar(pre,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                 if char and ligature[char] then
                     match = true
                 end
             end
-            if not match and not pre or not replace then
-                local n    = getnext(discfound)
-                local char = ischar(n,currentfont,currentscale,currentxscale,currentyscale)
+            if not match and (not pre or not replace) then
+                local nxt, char = isnextchar(getnext(discfound),currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                 if char and ligature[char] then
                     match = true
                 end
@@ -899,6 +923,8 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
                  -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
                     head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
                     logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
+                 -- we can have a rare case of multiple disc in a lig but that makes no sense language wise but if really
+                 -- needed we could backtrack if we're in a disc node
                 else
                  -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
                     head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
@@ -950,11 +976,11 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,st
         else
             local prev = start
             while snext do
-                local nextchar = ischar(snext,currentfont,currentscale,currentxscale,currentyscale)
+                local nxt, nextchar = isnextchar(snext,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                 if nextchar then
                     if skiphash and skiphash[nextchar] then -- includes marks too when flag
                         prev  = snext
-                        snext = getnext(snext)
+                        snext = nxt
                     else
                         local krn = kerns[nextchar]
                         if not krn then
@@ -1016,13 +1042,14 @@ function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,
     if marks[markchar] then
         local base = getprev(start) -- [glyph] [start=mark]
         if base then
-            local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+            local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if basechar then
                 if marks[basechar] then
+                    -- todo: use prv
                     while base do
                         base = getprev(base)
                         if base then
-                            basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+                            prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                             if basechar then
                                 if not marks[basechar] then
                                     break
@@ -1071,13 +1098,14 @@ function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlm
     if marks[markchar] then
         local base = getprev(start) -- [glyph] [optional marks] [start=mark]
         if base then
-            local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+            local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if basechar then
                 if marks[basechar] then
+                    -- todo: use prv
                     while base do
                         base = getprev(base)
                         if base then
-                            basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+                            prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                             if basechar then
                                 if not marks[basechar] then
                                     break
@@ -1147,7 +1175,7 @@ function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,
             end
         end
         if base then
-            local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+            local nxt, basechar = isnextchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if basechar then -- subtype test can go
                 local ba = markanchors[1][basechar] -- slot 1 has been made copy of the class hash
                 if ba then
@@ -1176,11 +1204,11 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,sk
     else
         local nxt = getnext(start)
         while nxt do
-            local nextchar = ischar(nxt,currentfont,currentscale,currentxscale,currentyscale)
+            local n, nextchar = isnextchar(nxt,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if not nextchar then
                 break
             elseif marks[nextchar] then -- always sequence.flags[1]
-                nxt = getnext(nxt)
+                nxt = n
             else
                 local exit = exitanchors[3]
                 if exit then
@@ -1330,7 +1358,7 @@ function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,r
     if mapping then
         local current = start
         while current do
-            local currentchar = ischar(current)
+            local nxt, currentchar = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if currentchar then
                 local replacement = mapping[currentchar]
                 if not replacement or replacement == "" then
@@ -1351,7 +1379,7 @@ function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,r
             elseif current == stop then
                 break
             else
-                current = getnext(current)
+                current = nxt
             end
         end
     end
@@ -1381,7 +1409,7 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku
         local value   = what == true and tfmdata.shared.features[kind] or what -- todo: optimize in ctx
         local current = start
         while current do
-            local currentchar = ischar(current)
+            local nxt, currentchar = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if currentchar then
                 local alternatives = mapping[currentchar]
                 if alternatives then
@@ -1405,7 +1433,7 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku
             elseif current == stop then
                 break
             else
-                current = getnext(current)
+                current = nxt
             end
         end
     end
@@ -1504,7 +1532,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
 --                     end
 --                 end
                 --
-                local nxt, schar, id = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale)
+                local nxt, schar, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                 if schar then
                     if skiphash and skiphash[schar] then -- marks
                         -- if current == stop then -- maybe add this
@@ -1615,13 +1643,12 @@ function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlm
                 if kerns then
                     local prev = start
                     while snext do
-                        local nextchar = ischar(snext,currentfont,currentscale,currentxscale,currentyscale)
+                        local nxt, nextchar = isnextchar(snext,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                         if not nextchar then
                             break
-                        end
-                        if skiphash and skiphash[nextchar] then
+                        elseif skiphash and skiphash[nextchar] then
                             prev  = snext
-                            snext = getnext(snext)
+                            snext = nxt
                         else
                             local krn = kerns[nextchar]
                             if not krn then
@@ -1684,13 +1711,14 @@ function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlooku
             if markanchors then
                 local base = getprev(start) -- [glyph] [start=mark]
                 if base then
-                    local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+                    local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                     if basechar then
                         if marks[basechar] then
+                            -- todo: use prv
                             while base do
                                 base = getprev(base)
                                 if base then
-                                    local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+                                    local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                                     if basechar then
                                         if not marks[basechar] then
                                             break
@@ -1749,13 +1777,14 @@ function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentl
             if markanchors then
                 local base = getprev(start) -- [glyph] [optional marks] [start=mark]
                 if base then
-                    local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+                    local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                     if basechar then
                         if marks[basechar] then
+                            -- todo: use prv
                             while base do
                                 base = getprev(base)
                                 if base then
-                                    local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+                                    local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                                     if basechar then
                                         if not marks[basechar] then
                                             break
@@ -1829,7 +1858,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlooku
                     end
                 end
                 if base then -- subtype test can go
-                    local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale)
+                    local nxt, basechar = isnextchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                     if basechar then
                         local ba = markanchors[1][basechar]
                         if ba then
@@ -1875,12 +1904,12 @@ function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,
             else
                 local nxt = getnext(start)
                 while nxt do
-                    local nextchar = ischar(nxt,currentfont,currentscale,currentxscale,currentyscale)
+                    local n, nextchar = isnextchar(nxt,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                     if not nextchar then
                         break
                     elseif marks[nextchar] then
                         -- should not happen (maybe warning)
-                        nxt = getnext(nxt)
+                        nxt = n
                     else
                         local exit = exitanchors[3]
                         if exit then
@@ -2050,10 +2079,10 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
             while start do
                 if skiphash then -- hm, so we know we skip some
                     while start do
-                        local char = ischar(start,currentfont,currentscale,currentxscale,currentyscale)
+                        local nxt, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                         if char then
                             if skiphash and skiphash[char] then
-                                start = getnext(start)
+                                start = nxt
                             else
                                 break
                             end
@@ -2311,7 +2340,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
         local insertedmarks = 0
 
         while cprev do
-            local char = ischar(cf,currentfont,currentscale,currentxscale,currentyscale)
+            local nxt, char = isnextchar(cf,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if char and marks[char] then
                 insertedmarks = insertedmarks + 1
                 cf            = cprev
@@ -2377,11 +2406,11 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
         local insertedmarks = 0
 
         while cnext do
-            local char = ischar(cnext,currentfont,currentscale,currentxscale,currentyscale)
+            local nxt, char = isnextchar(cnext,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if char and marks[char] then
                 insertedmarks = insertedmarks + 1
                 cl            = cnext
-                cnext         = getnext(cnext)
+                cnext         = nxt
             else
                 break
             end
@@ -2508,8 +2537,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
 
     local nofcontexts = contexts.n -- #contexts
 
-    local startchar = nofcontext == 1 or ischar(start,currentfont,currentscale,currentxscale,currentyscale) -- only needed in a chain
-
+    local startchar = nofcontext == 1 or ischar(start,currentfont) -- already checked
     for k=1,nofcontexts do -- does this disc mess work well with n > 1
 
         local ck  = contexts[k]
@@ -2541,8 +2569,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
                     sweeptype = nil
                 end
                 if last then
-                 -- local char, id = ischar(last,currentfont)
-                    local nxt, char, id = isnextchar(last,currentfont,currentscale,currentxscale,currentyscale)
+                    local nxt, char, id = isnextchar(last,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                     if char then
                         if skiphash and skiphash[char] then
                             skipped = true
@@ -2654,8 +2681,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
                     local n = f - 1
                     while n >= 1 do
                         if prev then
-                         -- local char, id = ischar(prev,currentfont)
-                            local prv, char, id = isprevchar(prev,currentfont,currentscale,currentxscale,currentyscale)
+                            local prv, char, id = isprevchar(prev,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                             if char then
                                 if skiphash and skiphash[char] then
                                     skipped = true
@@ -2792,8 +2818,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
                 local n = l + 1
                 while n <= s do
                     if current then
-                     -- local char, id = ischar(current,currentfont)
-                        local nxt, char, id = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale)
+                        local nxt, char, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
                         if char then
                             if skiphash and skiphash[char] then
                                 skipped = true
@@ -3104,7 +3129,7 @@ local function report_disc(what,n)
     report_run("%s: %s > %s",what,n,languages.serializediscretionary(n))
 end
 
-local function kernrun(disc,k_run,font,attr,...)
+local function kernrun(disc,k_run,...)
     --
     -- we catch <font 1><disc font 2>
     --
@@ -3125,30 +3150,30 @@ local function kernrun(disc,k_run,font,attr,...)
     -- has happened but then it should be in the disc so basically this test indicates an error)
     --
     while prevmarks do
-        local char = ischar(prevmarks,font)
+        local prv, char = isprevchar(prevmarks,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
         if char and marks[char] then
-            prevmarks = getprev(prevmarks)
+            prevmarks = prv
         else
             break
         end
     end
     --
-    if prev and not ischar(prev,font) then  -- and (pre or replace)
+    if prev and not ischar(prev,currentfont) then  -- and (pre or replace) -- weak test
         prev = false
     end
-    if next and not ischar(next,font) then  -- and (post or replace)
+    if next and not ischar(next,currentfont) then  -- and (post or replace) -- weak test
         next = false
     end
     --
     -- we need to get rid of this nest mess some day .. has to be done otherwise
     --
     if pre then
-        if k_run(pre,"injections",nil,font,attr,...) then
+        if k_run(pre,"injections",nil,...) then
             done = true
         end
         if prev then
             setlink(prev,pre)
-            if k_run(prevmarks,"preinjections",pre,font,attr,...) then -- or prev?
+            if k_run(prevmarks,"preinjections",pre,...) then -- or prev?
                 done = true
             end
             setprev(pre)
@@ -3157,12 +3182,12 @@ local function kernrun(disc,k_run,font,attr,...)
     end
     --
     if post then
-        if k_run(post,"injections",nil,font,attr,...) then
+        if k_run(post,"injections",nil,...) then
             done = true
         end
         if next then
             setlink(posttail,next)
-            if k_run(posttail,"postinjections",next,font,attr,...) then
+            if k_run(posttail,"postinjections",next,...) then
                 done = true
             end
             setnext(posttail)
@@ -3171,12 +3196,12 @@ local function kernrun(disc,k_run,font,attr,...)
     end
     --
     if replace then
-        if k_run(replace,"injections",nil,font,attr,...) then
+        if k_run(replace,"injections",nil,...) then
             done = true
         end
         if prev then
             setlink(prev,replace)
-            if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then -- getnext(replace))
+            if k_run(prevmarks,"replaceinjections",replace,...) then -- getnext(replace))
                 done = true
             end
             setprev(replace)
@@ -3184,7 +3209,7 @@ local function kernrun(disc,k_run,font,attr,...)
         end
         if next then
             setlink(replacetail,next)
-            if k_run(replacetail,"replaceinjections",next,font,attr,...) then
+            if k_run(replacetail,"replaceinjections",next,...) then
                 done = true
             end
             setnext(replacetail)
@@ -3192,7 +3217,7 @@ local function kernrun(disc,k_run,font,attr,...)
         end
     elseif prev and next then
         setlink(prev,next)
-        if k_run(prevmarks,"emptyinjections",next,font,attr,...) then
+        if k_run(prevmarks,"emptyinjections",next,...) then
             done = true
         end
         setlink(prev,disc,next)
@@ -3259,6 +3284,12 @@ end
 -- if we can hyphenate in a lig then unlikely a lig so we
 -- could have a option here to ignore lig
 
+local test_flatten_start = 2 -- must start at 2 according to Kai
+
+directives.register("otf.testrun.forceflatten", function(v)
+    test_flatten_start = v and 1 or 2
+end)
+
 local function testrun(disc,t_run,c_run,...)
     if trace_testruns then
         report_disc("test",disc)
@@ -3287,7 +3318,7 @@ local function testrun(disc,t_run,c_run,...)
             local d = d_replace > d_post and d_replace or d_post
             local head = getnext(disc) -- is: next
             local tail = head
-            for i=2,d do -- must start at 2 according to Kai
+            for i=test_flatten_start,d do
                 local nx = getnext(tail)
                 local id = getid(nx)
                 if id == disc_code then
@@ -3383,7 +3414,7 @@ end
 
 local nesting = 0
 
-local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+local function c_run_single(head,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
     local done  = false
     local sweep = sweephead[head]
     local start
@@ -3395,26 +3426,17 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm
         start = head
     end
     while start do
-        local char, id = ischar(start,font)
+        local nxt, char, id = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
         if char then
-            local a -- happens often so no assignment is faster
-            if attr then
-                a = getglyphdata(start)
-            end
-            if not a or (a == attr) then
-                local lookupmatch = lookupcache[char]
-                if lookupmatch then
-                    local ok
-                    head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
-                    if ok then
-                        done = true
-                    end
+            local lookupmatch = lookupcache[char]
+            if lookupmatch then
+                local ok
+                head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+                if ok then
+                    done = true
                 end
-                if start then
-                    start = getnext(start)
-                end
-            else
-                -- go on can be a mixed one
+            end
+            if start then
                 start = getnext(start)
             end
         elseif char == false then
@@ -3424,94 +3446,81 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm
             return head, done
         else
             -- in disc component
-            start = getnext(start)
+            start = nxt
         end
     end
     return head, done
 end
 
-local function t_run_single(start,stop,font,attr,lookupcache)
+local function t_run_single(start,stop,lookupcache)
     local lastd = nil
     while start ~= stop do
-        local char = ischar(start,font)
+        local nxt, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
         if char then
-            local a -- happens often so no assignment is faster
-            if attr then
-                a = getglyphdata(start)
-            end
-            local startnext = getnext(start)
-            if not a or (a == attr) then
-                local lookupmatch = lookupcache[char]
-                if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check
-                    -- if we need more than ligatures we can outline the code and use functions
-                    local s     = startnext
-                    local ss    = nil
-                    local sstop = s == stop
+            local lookupmatch = lookupcache[char]
+            if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check
+                -- if we need more than ligatures we can outline the code and use functions
+                local s     = startnext
+                local ss    = nil
+                local sstop = s == stop
+                if not s then
+                    s = ss
+                    ss = nil
+                end
+                -- a bit weird: why multiple ... anyway we can't have a disc in a disc
+                -- how about post ... we can probably merge this into the while
+                while getid(s) == disc_code do
+                    ss = getnext(s)
+                    s  = getreplace(s)
                     if not s then
                         s = ss
                         ss = nil
                     end
-                    -- a bit weird: why multiple ... anyway we can't have a disc in a disc
-                    -- how about post ... we can probably merge this into the while
-                    while getid(s) == disc_code do
-                        ss = getnext(s)
-                        s  = getreplace(s)
-                        if not s then
-                            s = ss
-                            ss = nil
-                        end
-                    end
-                    local l = nil
-                    local d = 0
-                    while s do
-                        local char = ischar(s,font)
-                        if char then
-                            local lg = lookupmatch[char]
-                            if lg then
-                                if sstop then
-                                    d = 1
-                                elseif d > 0 then
-                                    d = d + 1
-                                end
-                                l = lg
-                                s = getnext(s)
-                                sstop = s == stop
+                end
+                local l = nil
+                local d = 0
+                while s do
+                    local nxt, char = isnextchar(s,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
+                    if char then
+                        local lg = lookupmatch[char]
+                        if lg then
+                            if sstop then
+                                d = 1
+                            elseif d > 0 then
+                                d = d + 1
+                            end
+                            l = lg
+                            s = nxt
+                            sstop = s == stop
+                            if not s then
+                                s  = ss
+                                ss = nil
+                            end
+                            while getid(s) == disc_code do
+                                ss = getnext(s)
+                                s  = getreplace(s)
                                 if not s then
                                     s  = ss
                                     ss = nil
                                 end
-                                while getid(s) == disc_code do
-                                    ss = getnext(s)
-                                    s  = getreplace(s)
-                                    if not s then
-                                        s  = ss
-                                        ss = nil
-                                    end
-                                end
-                                lookupmatch = lg
-                            else
-                                break
                             end
+                            lookupmatch = lg
                         else
                             break
                         end
+                    else
+                        break
                     end
-                    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
-                else
-                    -- why not: break
-                    -- no match (yet)
                 end
-            else
-                -- go on can be a mixed one
-                -- why not: break
+                if l and l.ligature then -- so we test for ligature
+                    lastd = d
+                end
             end
             if lastd then
                 return lastd
+            else
+                start = startnext
             end
-            start = startnext
         else
             break
         end
@@ -3519,17 +3528,12 @@ local function t_run_single(start,stop,font,attr,lookupcache)
     return 0
 end
 
-local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
-    local a -- happens often so no assignment is faster
-    if attr then
-        a = getglyphdata(sub)
-    end
-    if not a or (a == attr) then
-        for n in nextnode, sub do -- only gpos
-            if n == last then
-                break
-            end
-            local char = ischar(n,font)
+local function k_run_single(sub,injection,last,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+    for n in nextnode, sub do -- only gpos
+        if n == last then
+            break
+        else
+            local nxt, char = isnextchar(n,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if char then
                 local lookupmatch = lookupcache[char]
                 if lookupmatch then
@@ -3543,25 +3547,7 @@ local function k_run_single(sub,injection,last,font,attr,lookupcache,step,datase
     end
 end
 
--- local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
---     for n in nextnode, sub do -- only gpos
---         if n == last then
---             break
---         end
---         local char = ischar(n,font,attr)
---         if char then
---             local lookupmatch = lookupcache[char]
---             if lookupmatch then
---                 local h, d, ok = handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
---                 if ok then
---                     return true
---                 end
---             end
---         end
---     end
--- end
-
-local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+local function c_run_multiple(head,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
     local done  = false
     local sweep = sweephead[head]
     local start
@@ -3573,35 +3559,26 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm
         start = head
     end
     while start do
-        local char = ischar(start,font)
+        local nxt, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
         if char then
-            local a -- happens often so no assignment is faster
-            if attr then
-                a = getglyphdata(start)
-            end
-            if not a or (a == attr) then
-                for i=1,nofsteps do
-                    local step        = steps[i]
-                    local lookupcache = step.coverage
-                    local lookupmatch = lookupcache[char]
-                    if lookupmatch then
-                        -- we could move all code inline but that makes things even more unreadable
-                        local ok
-                        head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
-                        if ok then
-                            done = true
-                            break
-                        elseif not start then
-                            -- don't ask why ... shouldn't happen
-                            break
-                        end
+            for i=1,nofsteps do
+                local step        = steps[i]
+                local lookupcache = step.coverage
+                local lookupmatch = lookupcache[char]
+                if lookupmatch then
+                    -- we could move all code inline but that makes things even more unreadable
+                    local ok
+                    head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+                    if ok then
+                        done = true
+                        break
+                    elseif not start then
+                        -- don't ask why ... shouldn't happen
+                        break
                     end
                 end
-                if start then
-                    start = getnext(start)
-                end
-            else
-                -- go on can be a mixed one
+            end
+            if start then
                 start = getnext(start)
             end
         elseif char == false then
@@ -3612,91 +3589,83 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm
             return head, done
         else
             -- in disc component
-            start = getnext(start)
+            start = nxt
         end
     end
     return head, done
 end
 
-local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
+local function t_run_multiple(start,stop,steps,nofsteps)
     local lastd = nil
     while start ~= stop do
-        local char = ischar(start,font)
+        local startnext, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
         if char then
-            local a -- happens often so no assignment is faster
-            if attr then
-                a = getglyphdata(start)
-            end
-            local startnext = getnext(start)
-            if not a or (a == attr) then
-                for i=1,nofsteps do
-                    local step = steps[i]
-                    local lookupcache = step.coverage
-                    local lookupmatch = lookupcache[char]
-                    if lookupmatch then
-                        -- if we need more than ligatures we can outline the code and use functions
-                        local s     = startnext
-                        local ss    = nil
-                        local sstop = s == stop
+            for i=1,nofsteps do
+                local step = steps[i]
+                local lookupcache = step.coverage
+                local lookupmatch = lookupcache[char]
+                if lookupmatch then
+                    -- if we need more than ligatures we can outline the code and use functions
+                    local s     = startnext
+                    local ss    = nil
+                    local sstop = s == stop
+                    if not s then
+                        s  = ss
+                        ss = nil
+                    end
+                    while getid(s) == disc_code do
+                        ss = getnext(s)
+                        s  = getreplace(s)
                         if not s then
                             s  = ss
                             ss = nil
                         end
-                        while getid(s) == disc_code do
-                            ss = getnext(s)
-                            s  = getreplace(s)
-                            if not s then
-                                s  = ss
-                                ss = nil
-                            end
-                        end
-                        local l = nil
-                        local d = 0
-                        while s do
-                            local char = ischar(s)
-                            if char then
-                                local lg = lookupmatch[char]
-                                if lg then
-                                    if sstop then
-                                        d = 1
-                                    elseif d > 0 then
-                                        d = d + 1
-                                    end
-                                    l = lg
-                                    s = getnext(s)
-                                    sstop = s == stop
+                    end
+                    local l = nil
+                    local d = 0
+                    while s do
+                        local nxt, char = isnextchar(s,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
+                        if char then
+                            local lg = lookupmatch[char]
+                            if lg then
+                                if sstop then
+                                    d = 1
+                                elseif d > 0 then
+                                    d = d + 1
+                                end
+                                l = lg
+                                s = nxt
+                                sstop = s == stop
+                                if not s then
+                                    s  = ss
+                                    ss = nil
+                                end
+                                while getid(s) == disc_code do
+                                    ss = getnext(s)
+                                    s  = getreplace(s)
                                     if not s then
                                         s  = ss
                                         ss = nil
                                     end
-                                    while getid(s) == disc_code do
-                                        ss = getnext(s)
-                                        s  = getreplace(s)
-                                        if not s then
-                                            s  = ss
-                                            ss = nil
-                                        end
-                                    end
-                                    lookupmatch = lg
-                                else
-                                    break
                                 end
+                                lookupmatch = lg
                             else
                                 break
                             end
+                        else
+                            break
                         end
-                        if l and l.ligature then
-                            lastd = d
-                        end
+                    end
+                    if l and l.ligature then
+                        lastd = d
                     end
                 end
-            else
-                -- go on can be a mixed one
             end
             if lastd then
                 return lastd
+            else
+                start = startnext
             end
-            start = startnext
         else
             break
         end
@@ -3704,17 +3673,12 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
     return 0
 end
 
-local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
-    local a -- happens often so no assignment is faster
-    if attr then
-        a = getglyphdata(sub)
-    end
-    if not a or (a == attr) then
-        for n in nextnode, sub do -- only gpos
-            if n == last then
-                break
-            end
-            local char = ischar(n)
+local function k_run_multiple(sub,injection,last,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+    for n in nextnode, sub do -- only gpos
+        if n == last then
+            break
+        else
+            local nxt, char = isnextchar(n,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if char then
                 for i=1,nofsteps do
                     local step        = steps[i]
@@ -3782,7 +3746,7 @@ otf.helpers.txtdirstate = txtdirstate
 otf.helpers.pardirstate = pardirstate
 
 -- This is the main loop. We run over the node list dealing with a specific font. The
--- attribute is a context specific thing. We could work on sub start-stop ranges instead
+-- dynamic is a context specific thing. We could work on sub start-stop ranges instead
 -- but I wonder if there is that much speed gain (experiments showed that it made not
 -- much sense) and we need to keep track of directions anyway. Also at some point I
 -- want to play with font interactions and then we do need the full sweeps. Apart from
@@ -3818,27 +3782,27 @@ do
         return v
     end }
 
-    function otf.featuresprocessor(head,font,attr,direction,n)
+    function otf.featuresprocessor(head,font,dynamic,direction,n)
 
         local sequences = sequencelists[font] -- temp hack
 
         nesting = nesting + 1
 
         if nesting == 1 then
-            currentfont   = font
-            currentattr   = attr
-            currentscale  = false
-            currentxscale = false
-            currentyscale = false
-            tfmdata       = fontdata[font]
-            descriptions  = tfmdata.descriptions -- only needed in gref so we could pass node there instead
-            characters    = tfmdata.characters   -- but this branch is not entered that often anyway
-      local resources     = tfmdata.resources
-            marks         = resources.marks
-            classes       = resources.classes
+            currentfont    = font
+            currentdynamic = dynamic
+            currentscale   = false
+            currentxscale  = false
+            currentyscale  = false
+            tfmdata        = fontdata[font]
+            descriptions   = tfmdata.descriptions -- only needed in gref so we could pass node there instead
+            characters     = tfmdata.characters   -- but this branch is not entered that often anyway
+      local resources      = tfmdata.resources
+            marks          = resources.marks
+            classes        = resources.classes
             threshold,
-            factor        = getthreshold(font)
-            checkmarks    = tfmdata.properties.checkmarks
+            factor         = getthreshold(font)
+            checkmarks     = tfmdata.properties.checkmarks
 
             if not otfdataset then
                 otfdataset = otf.dataset
@@ -3867,7 +3831,7 @@ do
             initialrl = -1
         end
 
-        local datasets  = otfdataset(tfmdata,font,attr)
+        local datasets  = otfdataset(tfmdata,font,dynamic)
         local dirstack  = { nil } -- could move outside function but we can have local runs
         sweephead       = { }
      -- sweephead  = { a = 1, b = 1 } sweephead.a = nil sweephead.b = nil
@@ -3880,7 +3844,7 @@ do
 
         for s=1,#datasets do
             local dataset      = datasets[s]
-            local attribute    = dataset[2]
+            local state        = dataset[2]
             local sequence     = dataset[3] -- sequences[s] -- also dataset[5]
             local rlparmode    = initialrl
             local topstack     = 0
@@ -3896,7 +3860,7 @@ do
                 -- This permits injection, watch the different arguments. Watch out, the arguments passed
                 -- are not frozen as we might extend or change this. Is this used at all apart from some
                 -- experiments?
-                local h, ok = handler(head,dataset,sequence,initialrl,font,attr) -- less arguments now
+                local h, ok = handler(head,dataset,sequence,initialrl,font,dynamic) -- less arguments now
                 if h and h ~= head then
                     head = h
                 end
@@ -3910,31 +3874,26 @@ do
                 local rlmode = 0 -- how important is this .. do we need to check for dir?
                 local merged = steps.merged
                 while start do
-                    local prv, char, id = isprevchar(start,font)
+                    local prv, char, id = isprevchar(start,font,dynamic,state)
                     if char then
                         local m = merged[char]
                         if m then
-                            local a
-                            a, currentscale, currentxscale, currentyscale = getwhatever(start,attr,attribute)
-                            if a then
-                                for i=m[1],m[2] do
-                                    local step = steps[i]
-                                    local lookupcache = step.coverage
-                                    local lookupmatch = lookupcache[char]
-                                    if lookupmatch then
-                                        local ok
-                                        head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
-                                        if ok then
-                                         -- done = true
-                                            break
-                                        end
+                            currentscale, currentxscale, currentyscale = getscales(start)
+                            for i=m[1],m[2] do
+                                local step = steps[i]
+                                local lookupcache = step.coverage
+                                local lookupmatch = lookupcache[char]
+                                if lookupmatch then
+                                    local ok
+                                    head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+                                    if ok then
+                                     -- done = true
+                                        break
                                     end
                                 end
-                                if start then
-                                    start = getprev(start)
-                                end
-                            else
-                                start = prv
+                            end
+                            if start then
+                                start = getprev(start)
                             end
                         else
                             start = prv
@@ -3950,30 +3909,24 @@ do
                     local step = steps[1]
                     local lookupcache = step.coverage
                     while start do
-                        local nxt, char, id = isnextchar(start,font) -- we can move the data/state checks here
+                        local nxt, char, id = isnextchar(start,font,dynamic,state) -- we can move the data/state checks here
                         if char then
                             if skiphash and skiphash[char] then -- we never needed it here but let's try
                                 start = nxt
                             else
                                 local lookupmatch = lookupcache[char]
                                 if lookupmatch then
-                                    local a
-                                    a, currentscale, currentxscale, currentyscale = getwhatever(start,attr,attribute)
-                                    if a then
-                                        local ok, df
-                                        head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
-                                        if df then
-                                         -- print("restart 1",typ)
-                                        elseif start then
-                                            start = getnext(start) -- can be a new start
-                                        end
-                                    else
-                                        start = nxt
+                                    currentscale, currentxscale, currentyscale = getscales(start)
+                                    local ok, df
+                                    head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+                                    if df then
+                                     -- print("restart 1",typ)
+                                    elseif start then
+                                        start = getnext(start) -- can be a new start
                                     end
                                 else
                                     start = nxt
                                 end
-
                             end
                         elseif char == false or id == glue_code then
                             -- a different font|state or glue (happens often)
@@ -3982,11 +3935,11 @@ do
                             if not discs or discs[start] == true then
                                 local ok
                                 if gpossing then
-                                    start, ok = kernrun(start,k_run_single,             font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+                                    start, ok = kernrun(start,k_run_single,             lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
                                 elseif forcetestrun then
-                                    start, ok = testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+                                    start, ok = testrun(start,t_run_single,c_run_single,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
                                 else
-                                    start, ok = comprun(start,c_run_single,             font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+                                    start, ok = comprun(start,c_run_single,             lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
                                 end
                              -- if ok then
                              --     done = true
@@ -4009,42 +3962,37 @@ do
                 else
                     local merged = steps.merged
                     while start do
-                        local nxt, char, id = isnextchar(start,font)
+                        local nxt, char, id = isnextchar(start,font,dynamic,state)
                         if char then
                             if skiphash and skiphash[char] then -- we never needed it here but let's try
                                 start = nxt
                             else
                                 local m = merged[char]
                                 if m then
-                                    local a
-                                    a, currentscale, currentxscale, currentyscale = getwhatever(start,attr,attribute)
-                                    if a then
-                                        local ok, df
-                                        for i=m[1],m[2] do
-                                            local step = steps[i]
-                                            local lookupcache = step.coverage
-                                            local lookupmatch = lookupcache[char]
-                                            if lookupmatch then
-                                                -- we could move all code inline but that makes things even more unreadable
+                                    currentscale, currentxscale, currentyscale = getscales(start)
+                                    local ok, df
+                                    for i=m[1],m[2] do
+                                        local step = steps[i]
+                                        local lookupcache = step.coverage
+                                        local lookupmatch = lookupcache[char]
+                                        if lookupmatch then
+                                            -- we could move all code inline but that makes things even more unreadable
 --                                                 local ok, df
-                                                head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
-                                                if df then
-                                                    break
-                                                elseif ok then
-                                                    break
-                                                elseif not start then
-                                                    -- don't ask why ... shouldn't happen
-                                                    break
-                                                end
+                                            head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+                                            if df then
+                                                break
+                                            elseif ok then
+                                                break
+                                            elseif not start then
+                                                -- don't ask why ... shouldn't happen
+                                                break
                                             end
                                         end
-                                        if df then
-                                         -- print("restart 2",typ)
-                                        elseif start then
-                                            start = getnext(start) -- can be a new next
-                                        end
-                                    else
-                                        start = nxt
+                                    end
+                                    if df then
+                                     -- print("restart 2",typ)
+                                    elseif start then
+                                        start = getnext(start) -- can be a new next
                                     end
                                 else
                                     start = nxt
@@ -4057,11 +4005,11 @@ do
                             if not discs or discs[start] == true then
                                 local ok
                                 if gpossing then
-                                    start, ok = kernrun(start,k_run_multiple,               font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+                                    start, ok = kernrun(start,k_run_multiple,               steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
                                 elseif forcetestrun then
-                                    start, ok = testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+                                    start, ok = testrun(start,t_run_multiple,c_run_multiple,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
                                 else
-                                    start, ok = comprun(start,c_run_multiple,               font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+                                    start, ok = comprun(start,c_run_multiple,               steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
                                 end
                             else
                                 start = nxt
@@ -4098,6 +4046,7 @@ do
     function otf.datasetpositionprocessor(head,font,direction,dataset)
 
         currentfont     = font
+        currentdynamic  = false
         currentscale    = false
         currentxscale   = false
         currentyscale   = false
@@ -4142,8 +4091,7 @@ do
         local position  = 0
 
         while start do
-         -- local char, id = ischar(start,font)
-            local nxt, char, id = isnextchar(start,font)
+            local nxt, char, id = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
             if char then
                 position = position + 1
                 local m = merged[char]
@@ -4240,14 +4188,14 @@ function otf.plugininitializer(tfmdata,value)
     end
 end
 
-function otf.pluginprocessor(head,font,attr,direction) -- n
+function otf.pluginprocessor(head,font,dynamic,direction) -- n
     local s = fontdata[font].shared
     local p = s and s.plugin
     if p then
         if trace_plugins then
             report_process("applying plugin %a",p[1])
         end
-        return p[2](head,font,attr,direction)
+        return p[2](head,font,dynamic,direction)
     else
         return head, false
     end
@@ -4294,7 +4242,7 @@ registerotffeature {
 -- when a handler has steps, it is called as the other ones, but when we have no steps,
 -- we use a different call:
 --
---   function(head,dataset,sequence,initialrl,font,attr)
+--   function(head,dataset,sequence,initialrl,font,dynamic)
 --       return head, done
 --   end
 --
@@ -4314,7 +4262,7 @@ local tag = "kern"
 
 -- if fontfeatures then
 
---     function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+--     function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,dynamic)
 --         local features = fontfeatures[font]
 --         local enabled  = features and features.spacekern and features[tag]
 --         if enabled then
@@ -4325,7 +4273,7 @@ local tag = "kern"
 
 -- else -- generic (no hashes)
 
-    function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+    function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,dynamic)
         local shared   = fontdata[font].shared
         local features = shared and shared.features
         local enabled  = features and features.spacekern and features[tag]
@@ -4409,7 +4357,7 @@ otf.readers.registerextender {
     end
 }
 
-local function spaceinitializer(tfmdata,value) -- attr
+local function spaceinitializer(tfmdata,value) -- dynamic
     local resources  = tfmdata.resources
     local spacekerns = resources and resources.spacekerns
     if value and spacekerns == nil then
diff --git a/tex/context/base/mkxl/lang-ini.mkxl b/tex/context/base/mkxl/lang-ini.mkxl
index e115ce9f8..2644d1d76 100644
--- a/tex/context/base/mkxl/lang-ini.mkxl
+++ b/tex/context/base/mkxl/lang-ini.mkxl
@@ -756,7 +756,18 @@
      {\clf_currentposthyphenchar post}%
      {replace}}
 
-%D Also new:
+%D A typical \LMTX\ feature:
+%D
+%D \starttyping
+%D whatever\par
+%D {\nokerning whatever}\par
+%D efficient ff fi\par
+%D {\noligaturing efficient ff fi}\par
+%D {\nokerning\noligaturing efficient ff fi}\par
+%D {e{\noligaturing ffi}cient}\par
+%D {ef{\noleftligaturing f}icient ff fi}\par
+%D {ef{\norightligaturing f}icient ff fi}\par
+%D \stoptyping
 
 \immutable\chardef\nokerningcode   \numexpr\noleftkerncode    +\norightkerncode    \relax
 \immutable\chardef\noligaturingcode\numexpr\noleftligaturecode+\norightligaturecode\relax
@@ -764,4 +775,9 @@
 \permanent\protected\def\nokerning   {\bitwiseflip\glyphoptions\nokerningcode}
 \permanent\protected\def\noligaturing{\bitwiseflip\glyphoptions\noligaturingcode}
 
+\permanent\protected\def\noleftkerning    {\bitwiseflip\glyphoptions\noleftkerncode}
+\permanent\protected\def\noleftligaturing {\bitwiseflip\glyphoptions\noleftligaturecode}
+\permanent\protected\def\norightkerning   {\bitwiseflip\glyphoptions\norightkerncode}
+\permanent\protected\def\norightligaturing{\bitwiseflip\glyphoptions\norightligaturecode}
+
 \protect \endinput
diff --git a/tex/context/base/mkxl/node-fnt.lmt b/tex/context/base/mkxl/node-fnt.lmt
index 658ea46bb..c96bdde3d 100644
--- a/tex/context/base/mkxl/node-fnt.lmt
+++ b/tex/context/base/mkxl/node-fnt.lmt
@@ -60,8 +60,6 @@ local setprev           = nuts.setprev
 local isglyph           = nuts.isglyph -- unchecked
 local ischar            = nuts.ischar  -- checked
 
------ traverse_id       = nuts.traverse_id
------ traverse_char     = nuts.traverse_char
 local nextboundary      = nuts.traversers.boundary
 local nextdisc          = nuts.traversers.disc
 local nextchar          = nuts.traversers.char
@@ -88,14 +86,6 @@ local run = 0
 local setfontdynamics = { }
 local fontprocesses   = { }
 
--- setmetatableindex(setfontdynamics, function(t,font)
---     local tfmdata = fontdata[font]
---     local shared = tfmdata.shared
---     local v = shared and shared.dynamics and otf.setdynamics or false
---     t[font] = v
---     return v
--- end)
-
 setmetatableindex(setfontdynamics, function(t,font)
     local tfmdata = fontdata[font]
     local shared = tfmdata.shared
@@ -156,8 +146,8 @@ local function start_trace(head)
         local char, id = isglyph(n)
         if char then
             local font = id
-            local attr = getglyphdata(n) or 0
-            report_fonts("font %03i, dynamic %03i, glyph %C",font,attr,char)
+            local dynamic = getglyphdata(n) or 0
+            report_fonts("font %03i, dynamic %03i, glyph %C",font,dynamic,char)
         elseif id == disc_code then
             report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n))
         elseif id == boundary_code then
@@ -169,10 +159,10 @@ local function start_trace(head)
     end
 end
 
-local function stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant)
+local function stop_trace(u,usedfonts,d,dynamicfonts,b,basefonts,r,redundant)
     report_fonts()
     report_fonts("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none")
-    report_fonts("dynamics: %s",a > 0 and concat(keys(attrfonts)," ") or "none")
+    report_fonts("dynamics: %s",d > 0 and concat(keys(dynamicfonts)," ") or "none")
     report_fonts("built-in: %s",b > 0 and b or "none")
     report_fonts("removed : %s",r > 0 and r or "none")
     report_fonts()
@@ -181,11 +171,11 @@ end
 do
 
     local usedfonts
-    local attrfonts
+    local dynamicfonts
     local basefonts  -- could be reused
     local basefont
     local prevfont
-    local prevattr
+    local prevdynamic
     local variants
     local redundant  -- could be reused
     local firstnone
@@ -193,7 +183,7 @@ do
     local lastproc
     local lastnone
 
-    local a, u, b, r
+    local d, u, b, r
 
     local function protectnone()
         protect_glyphs(firstnone,lastnone)
@@ -228,7 +218,7 @@ do
         end
     end
 
-    local function setnode(n,font,attr) -- we could use prevfont and prevattr when we set then first
+    local function setnode(n,font,dynamic) -- we could use prevfont and prevdynamic when we set then first
         if firstnone then
             protectnone()
         end
@@ -236,17 +226,17 @@ do
             basefont[2] = getprev(n)
             basefont = false
         end
-        if attr > 0 then
-            local used = attrfonts[font]
+        if dynamic > 0 then
+            local used = dynamicfonts[font]
             if not used then
                 used = { }
-                attrfonts[font] = used
+                dynamicfonts[font] = used
             end
-            if not used[attr] then
+            if not used[dynamic] then
                 local fd = setfontdynamics[font]
                 if fd then
-                    used[attr] = fd[attr]
-                    a = a + 1
+                    used[dynamic] = fd[dynamic]
+                    d = d + 1
                 end
             end
         else
@@ -266,22 +256,22 @@ do
         -- either next or not, but definitely no already processed list
         starttiming(nodes)
 
-        usedfonts = { }
-        attrfonts = { }
-        basefonts = { }
-        basefont  = nil
-        prevfont  = nil
-        prevattr  = 0
-        variants  = nil
-        redundant = nil
-        firstnone = nil
-        lastfont  = nil
-        lastproc  = nil
-        lastnone  = nil
+        usedfonts    = { }
+        dynamicfonts = { }
+        basefonts    = { }
+        basefont     = nil
+        prevfont     = nil
+        prevdynamic  = 0
+        variants     = nil
+        redundant    = nil
+        firstnone    = nil
+        lastfont     = nil
+        lastproc     = nil
+        lastnone     = nil
 
-local fontmode = nil
+        local fontmode = nil -- base none or other
 
-        a, u, b, r = 0, 0, 0, 0
+        d, u, b, r = 0, 0, 0, 0
 
         if trace_fontrun then
             start_trace(head)
@@ -290,48 +280,31 @@ local fontmode = nil
         -- There is no gain in checking for a single glyph and then having a fast path. On the
         -- metafun manual (with some 2500 single char lists) the difference is just noise.
 
-        for n, char, font in nextchar, head do
-
---            local attr = getglyphdata(n) or 0 -- zero attribute is reserved for fonts in context
---            if font ~= prevfont or attr ~= prevattr then
---                prevfont = font
---                prevattr = attr
---                variants = fontvariants[font]
---                local fontmode = fontmodes[font]
---                if fontmode == "none" then
---                    setnone(n)
---                elseif fontmode == "base" then
---                    setbase(n)
---                else
---                    setnode(n,font,attr)
---                end
---            elseif firstnone then
---                lastnone = n
---            end
+        for n, char, font, dynamic in nextchar, head do
 
             if font ~= prevfont then
                 prevfont = font
                 fontmode = fontmodes[font]
                 if fontmode == "none" then
-                    prevattr = 0
-                    variants = false
+                    prevdynamic = 0
+                    variants    = false
                     setnone(n)
                 elseif fontmode == "base" then
-                    prevattr = 0
-                    variants = false
+                    prevdynamic = 0
+                    variants    = false
                     setbase(n)
                 else
-                    local attr = getglyphdata(n) or 0 -- zero attribute is reserved for fonts in context
-                    prevattr = attr
-                    variants = fontvariants[font]
-                    setnode(n,font,attr)
+                 -- local dynamic = getglyphdata(n) or 0 -- zero dynamic is reserved for fonts in context
+                    prevdynamic = dynamic
+                    variants    = fontvariants[font]
+                    setnode(n,font,dynamic)
                 end
             elseif fontmode == "node" then
-                local attr = getglyphdata(n) or 0 -- zero attribute is reserved for fonts in context
-                if attr ~= prevattr then
-                    prevattr = attr
-                    variants = fontvariants[font]
-                    setnode(n,font,attr)
+                local dynamic = getglyphdata(n) or 0 -- zero dynamic is reserved for fonts in context
+                if dynamic ~= prevdynamic then
+                    prevdynamic = dynamic
+                    variants    = fontvariants[font]
+                    setnode(n,font,dynamic)
                 end
             elseif firstnone then
                 lastnone = n
@@ -434,21 +407,21 @@ local fontmode = nil
             -- basefont is not supported in disc only runs ... it would mean a lot of
             -- ranges .. we could try to run basemode as a separate processor run but not
             -- for now (we can consider it when the new node code is tested
-            for d in nextdisc, head do
+            for disc in nextdisc, head do
                 -- doing only replace is good enough because pre and post are normally used
                 -- for hyphens and these come from fonts that part of the hyphenated word
-                local r = getreplace(d)
+                local r = getreplace(disc)
                 if r then
-                    local prevfont = nil
-                    local prevattr = nil
-                    local none     = false
-                    firstnone = nil
-                    basefont  = nil
-                    for n, char, font in nextchar, r do
-                        local attr = getglyphdata(n) or 0 -- zero attribute is reserved for fonts in context
-                        if font ~= prevfont or attr ~= prevattr then
-                            prevfont = font
-                            prevattr = attr
+                    local prevfont    = nil
+                    local prevdynamic = nil
+                    local none        = false
+                          firstnone   = nil
+                          basefont    = nil
+                    for n, char, font, dynamic in nextchar, r do
+                     -- local dynamic = getglyphdata(n) or 0 -- zero dynamic is reserved for fonts in context
+                        if font ~= prevfont or dynamic ~= prevdynamic then
+                            prevfont    = font
+                            prevdynamic = dynamic
                             local fontmode = fontmodes[font]
                             if fontmode == "none" then
                                 setnone(n)
@@ -456,7 +429,7 @@ local fontmode = nil
                                 -- so the replace gets an extra treatment ... so be it
                                 setbase(n)
                             else
-                                setnode(n,font,attr)
+                                setnode(n,font,dynamic)
                             end
                         elseif firstnone then
                          -- lastnone = n
@@ -475,40 +448,37 @@ local fontmode = nil
         end
 
         if trace_fontrun then
-            stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant)
+            stop_trace(u,usedfonts,d,dynamicfonts,b,basefonts,r,redundant)
         end
 
         -- in context we always have at least 2 processors
         if u == 0 then
             -- skip
         elseif u == 1 then
-            local attr = a > 0 and 0 or false -- 0 is the savest way
             for i=1,#lastproc do
-                head = lastproc[i](head,lastfont,attr,direction)
+                head = lastproc[i](head,lastfont,0,direction)
             end
         else
-         -- local attr = a == 0 and false or 0 -- 0 is the savest way
-            local attr = a > 0 and 0 or false -- 0 is the savest way
             for font, processors in next, usedfonts do -- unordered
                 for i=1,#processors do
-                    head = processors[i](head,font,attr,direction,u)
+                    head = processors[i](head,font,0,direction,u) -- u triggers disc optimizer
                 end
             end
         end
-        if a == 0 then
+        if d == 0 then
             -- skip
-        elseif a == 1 then
-            local font, dynamics = next(attrfonts)
-            for attribute, processors in next, dynamics do -- unordered, attr can switch in between
+        elseif d == 1 then
+            local font, dynamics = next(dynamicfonts)
+            for dynamic, processors in next, dynamics do -- unordered, dynamic can switch in between
                 for i=1,#processors do
-                    head = processors[i](head,font,attribute,direction)
+                    head = processors[i](head,font,dynamic,direction)
                 end
             end
         else
-            for font, dynamics in next, attrfonts do
-                for attribute, processors in next, dynamics do -- unordered, attr can switch in between
+            for font, dynamics in next, dynamicfonts do
+                for dynamic, processors in next, dynamics do -- unordered, dynamic can switch in between
                     for i=1,#processors do
-                        head = processors[i](head,font,attribute,direction,a)
+                        head = processors[i](head,font,dynamic,direction,d) -- d triggers disc optimizer
                     end
                 end
             end
diff --git a/tex/context/base/mkxl/node-nut.lmt b/tex/context/base/mkxl/node-nut.lmt
index 7b36d1752..dbd5c7ef2 100644
--- a/tex/context/base/mkxl/node-nut.lmt
+++ b/tex/context/base/mkxl/node-nut.lmt
@@ -102,7 +102,6 @@ local nuts = {
     getyscale               = direct.getyscale,
     getxyscales             = direct.getxyscales,
     getorientation          = direct.getorientation,
-    getwhatever             = direct.getwhatever, -- experimental hook
     getoptions              = direct.getoptions,
     getpenalty              = direct.getpenalty,
     getpost                 = direct.getpost,
@@ -236,6 +235,7 @@ local nuts = {
     write                   = direct.write,
     append                  = direct.append,
     has_glyph_option        = direct.has_glyph_option,
+    show                    = direct.show,
 }
 
 nodes.nuts      = nuts
diff --git a/tex/context/base/mkxl/node-tra.lmt b/tex/context/base/mkxl/node-tra.lmt
index f985652c5..da3cb1d33 100644
--- a/tex/context/base/mkxl/node-tra.lmt
+++ b/tex/context/base/mkxl/node-tra.lmt
@@ -59,6 +59,8 @@ local used_nodes      = nuts.usedlist
 local nextnode        = nuts.traversers.node
 local nextglyph       = nuts.traversers.glyph
 
+local shownodes       = nuts.show
+
 local d_tostring      = nuts.tostring
 
 local nutpool         = nuts.pool
@@ -722,3 +724,16 @@ tracers.rule = nodestracerpool.rule -- for a while
 --     end
 --     print("STOP", message or "")
 -- end
+
+function nodes.handlers.show(n)
+    if n then
+        shownodes(tonut(n))
+    else
+        -- maybe a message
+    end
+    return n
+end
+
+trackers.register("fonts.result.show", function(v)
+    nodes.tasks.setaction("processors","nodes.handlers.show",v)
+end)
diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml
index c7cdcfa74..dc2cc49c3 100644
--- a/tex/context/interface/mkii/keys-en.xml
+++ b/tex/context/interface/mkii/keys-en.xml
@@ -1137,6 +1137,7 @@
 		<cd:constant name='reference' value='reference'/>
 		<cd:constant name='referencemethod' value='referencemethod'/>
 		<cd:constant name='referenceprefix' value='referenceprefix'/>
+		<cd:constant name='referencetext' value='referencetext'/>
 		<cd:constant name='referencing' value='referencing'/>
 		<cd:constant name='region' value='region'/>
 		<cd:constant name='regionin' value='regionin'/>
diff --git a/tex/context/modules/mkiv/s-fonts-variable.mkiv b/tex/context/modules/mkiv/s-fonts-variable.mkiv
index 7a9d82c5a..6e4b1773f 100644
--- a/tex/context/modules/mkiv/s-fonts-variable.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-variable.mkiv
@@ -103,6 +103,12 @@
 %  \showfontvariations
 %    [font=file:sourcecode-regular.otf]
 
+% \showfontvariations
+%   [font=file:sourcecodevariable-roman.otf]
+
+% \showfontvariations
+%   [font=file:sourcecodevariable-italic.otf]
+
 %  \showfontvariations
 %    [font=file:AmstelvarAlpha-VF.ttf]
 
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 1b6212597..dde25ac75 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
 -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
 -- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date  : 2021-01-05 10:41
+-- merge date  : 2021-01-07 16:56
 
 do -- begin closure to overcome local limits and interference
 
@@ -14019,7 +14019,7 @@ do
  local reginit=false
  local function updateregions(n) 
   if regions then
-   local current=regions[n] or regions[1]
+   local current=regions[n+1] or regions[1]
    nofregions=#current
    if axis and n~=reginit then
     factors={}
@@ -14588,7 +14588,11 @@ do
   popped=3
   seacs={}
   if regions then
-   regions={ regions } 
+   regions={}
+   local deltas=data.deltas
+   for i=1,#deltas do
+    regions[i]=deltas[i].regions
+   end
    axis=data.factors or false
   end
  end
@@ -16573,7 +16577,6 @@ local function readvariationdata(f,storeoffset,factors)
   end
   regions[i]=t
  end
- if factors then
   for i=1,nofdeltadata do
    setposition(f,storeoffset+deltadata[i])
    local nofdeltasets=readushort(f)
@@ -16597,7 +16600,6 @@ local function readvariationdata(f,storeoffset,factors)
     scales=factors and getscales(usedregions,factors) or nil,
    }
   end
- end
  setposition(f,position)
  return regions,deltadata
 end
@@ -20782,7 +20784,7 @@ local trace_defining=false  registertracker("fonts.defining",function(v) trace_d
 local report_otf=logs.reporter("fonts","otf loading")
 local fonts=fonts
 local otf=fonts.handlers.otf
-otf.version=3.112 
+otf.version=3.113 
 otf.cache=containers.define("fonts","otl",otf.version,true)
 otf.svgcache=containers.define("fonts","svg",otf.version,true)
 otf.pngcache=containers.define("fonts","png",otf.version,true)
-- 
cgit v1.2.3