From bc20cf026cb0d2a175c116c5840d167f341d885e Mon Sep 17 00:00:00 2001 From: Marius Date: Sat, 26 Mar 2011 14:00:13 +0200 Subject: beta 2011.03.26 12:41 --- tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 2 +- tex/context/base/font-con.lua | 23 +- tex/context/base/font-ctx.lua | 3 +- tex/context/base/font-ext.lua | 16 +- tex/context/base/node-fnt.lua | 38 ++-- tex/context/base/status-files.pdf | Bin 23564 -> 23563 bytes tex/context/base/x-ldx.ctx | 23 ++ tex/context/base/x-ldx.lua | 326 ++++++++++++++++++++++++++++ tex/context/base/x-ldx.mkiv | 186 ++++++++++++++++ tex/generic/context/luatex-fonts-merged.lua | 25 ++- 13 files changed, 600 insertions(+), 48 deletions(-) create mode 100644 tex/context/base/x-ldx.ctx create mode 100644 tex/context/base/x-ldx.lua create mode 100644 tex/context/base/x-ldx.mkiv (limited to 'tex') diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index e6239cf11..c0af3ec21 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2011.03.26 11:35} +\newcontextversion{2011.03.26 12:41} %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/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 8a87d5d6d..8aed059b9 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2011.03.26 11:35} +\newcontextversion{2011.03.26 12:41} %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/context.mkii b/tex/context/base/context.mkii index 87de9a1ae..f96fa884e 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2011.03.26 11:35} +\edef\contextversion{2011.03.26 12:41} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index da17e89a1..97a319cf4 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2011.03.26 11:35} +\edef\contextversion{2011.03.26 12:41} %D For those who want to use this: diff --git a/tex/context/base/font-con.lua b/tex/context/base/font-con.lua index 230136929..434f64215 100644 --- a/tex/context/base/font-con.lua +++ b/tex/context/base/font-con.lua @@ -1046,16 +1046,14 @@ a helper function.

function constructors.checkedfeatures(what,features) if features and next(features) then - local done = false for key, value in next, handlers[what].features.defaults do if features[key] == nil then features[key] = value - done = true end end - return features, done -- done signals a change + return features else - return fastcopy(defaults), true + return fastcopy(defaults) end end @@ -1068,9 +1066,11 @@ function constructors.initializefeatures(what,tfmdata,features,trace,report) local whatfeatures = whathandler.features local whatinitializers = whatfeatures.initializers local whatmodechecker = whatfeatures.modechecker - local mode = properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features)) or features.mode or "base" - properties.mode = mode -- also status - local done = { } + -- properties.mode can be enforces (for instance in font-otd) + local mode = properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" + properties.mode = mode -- also status + -- + local done = { } while true do local redo = false local initializers = whatfeatures.initializers[mode] @@ -1091,8 +1091,13 @@ function constructors.initializefeatures(what,tfmdata,features,trace,report) end action(tfmdata,value,features) -- can set mode (e.g. goodies) so it can trigger a restart if mode ~= properties.mode then - mode = properties.mode - redo = true + if whatmodechecker then + properties.mode = whatmodechecker(tfmdata,features,properties.mode) -- force checking + end + if mode ~= properties.mode then + mode = properties.mode + redo = true + end end done[feature] = true end diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index f425b79de..d3886eee8 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -130,8 +130,7 @@ end) -- this cannot be a feature initializer as there is no auto namespace -- so we never enter the loop then -local function modechecker(tfmdata,features) -- we cannot adapt features as they are shared! - local mode = features.mode +local function modechecker(tfmdata,features,mode) -- we cannot adapt features as they are shared! if mode == "auto" then local script = features.script local language = features.language diff --git a/tex/context/base/font-ext.lua b/tex/context/base/font-ext.lua index acabdb465..97bee4d67 100644 --- a/tex/context/base/font-ext.lua +++ b/tex/context/base/font-ext.lua @@ -27,8 +27,6 @@ of neutral.

--ldx]]-- local fonts = fonts -local handlers = fonts.handlers -local otf = handlers.otf local otffeatures = fonts.constructors.newfeatures("otf") local registerotffeature = otffeatures.register @@ -42,7 +40,7 @@ local registerafmfeature = afmfeatures.register local function get_class_and_vector(tfmdata,value,where) -- "expansions" local g_where = tfmdata.goodies and tfmdata.goodies[where] - local f_where = handlers[where] + local f_where = fonts[where] local g_classes = g_where and g_where.classes local f_classes = f_where and f_where.classes local class = (g_classes and g_classes[value]) or (f_classes and f_classes[value]) @@ -380,7 +378,9 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd) end end end - tfmdata.auto_protrude = done + tfmdata.parameters.protrusion { + auto = true + } end -- The opbd test is just there because it was discussed on the @@ -453,8 +453,8 @@ local function initializeprotrusion(tfmdata,value) end registerotffeature { - name = "protrusion", - description = "shift characters into the left and or right margin", + name = "protrusion", + description = "shift characters into the left and or right margin", initializers = { base = initializeprotrusion, node = initializeprotrusion, @@ -462,8 +462,8 @@ registerotffeature { } registerafmfeature { - name = "protrusion", - description = "shift characters into the left and or right margin", + name = "protrusion", + description = "shift characters into the left and or right margin", initializers = { base = initializeprotrusion, node = initializeprotrusion, diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua index 23cf0c04d..77aa79396 100644 --- a/tex/context/base/node-fnt.lua +++ b/tex/context/base/node-fnt.lua @@ -171,21 +171,9 @@ function handlers.characters(head) local font, dynamics = next(attrfonts) for attribute, processors in next, dynamics do -- attr can switch in between local n = #processors - local h, d = processors[1](head,font,attribute) - head = h or head - done = done or d - if n > 1 then - for i=2,n do - local h, d = processors[i](head,font,attribute) - head = h or head - done = done or d - end - end - end - elseif a > 0 then - for font, dynamics in next, attrfonts do - for attribute, processors in next, dynamics do -- attr can switch in between - local n = #processors + if n == 0 then + report_fonts("no processors associated with dynamic %s",attribute) + else local h, d = processors[1](head,font,attribute) head = h or head done = done or d @@ -198,6 +186,26 @@ function handlers.characters(head) end end end + elseif a > 0 then + for font, dynamics in next, attrfonts do + for attribute, processors in next, dynamics do -- attr can switch in between + local n = #processors + if n == 0 then + report_fonts("no processors associated with dynamic %s",attribute) + else + local h, d = processors[1](head,font,attribute) + head = h or head + done = done or d + if n > 1 then + for i=2,n do + local h, d = processors[i](head,font,attribute) + head = h or head + done = done or d + end + end + end + end + end end stoptiming(nodes) if trace_characters then diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 453aa9d08..9b377e8a1 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/x-ldx.ctx b/tex/context/base/x-ldx.ctx new file mode 100644 index 000000000..0dddc9734 --- /dev/null +++ b/tex/context/base/x-ldx.ctx @@ -0,0 +1,23 @@ + + + + Lua Documentation Generator + + + mtxrun --internal x-ldx.lua + + + + + + + purge + forcexml + + + + ldx + + + + diff --git a/tex/context/base/x-ldx.lua b/tex/context/base/x-ldx.lua new file mode 100644 index 000000000..18e7b9b38 --- /dev/null +++ b/tex/context/base/x-ldx.lua @@ -0,0 +1,326 @@ +--[[ldx-- +Lua Documentation Module + +This file is part of the documentation suite and +itself serves as an example of using in combination +with . + +I will rewrite this using lpeg once I have the time to study that nice new +subsystem. On the other hand, we cannot expect proper +ad for educational purposed the syntax migh be wrong. +--ldx]]-- + +-- there is anice parser on from http://lua-users.org/wiki/LpegRecipes (by +-- Patrick Donnelly) but lua crashes when I apply functions to some of the +-- matches + +banner = "version 1.0.1 - 2007+ - PRAGMA ADE / CONTEXT" + +--[[ +This script needs a few libraries. Instead of merging the code here +we can use + + +mtxrun --internal x-ldx.lua + + +That way, the libraries included in the runner will be used. +]]-- + +-- libraries l-string.lua l-table.lua l-io.lua l-file.lua + +-- begin library merge +-- end library merge + +--[[ +Just a demo comment line. We will handle such multiline comments but +only when they start and end at the beginning of a line. More rich +comments are tagged differently. +]]-- + +--[[ldx-- +First we define a proper namespace for this module. The l stands for +, the d for documentation and the x for +. +--ldx]]-- + +if not ldx then ldx = { } end + +--[[ldx-- +We load the lua file into a table. The entries in this table themselves are +tables and have keys like code and comment. +--ldx]]-- + +function ldx.load(filename) + local data = file.readdata(filename) + local expr = "%s*%-%-%[%[ldx%-*%s*(.-)%s*%-%-ldx%]%]%-*%s*" + local i, j, t = 0, 0, { } + while true do + local comment, ni + ni, j, comment = data:find(expr, j) + if not ni then break end + t[#t+1] = { code = data:sub(i, ni-1) } + t[#t+1] = { comment = comment } + i = j + 1 + end + local str = data:sub(i, #data) + str = str:gsub("^%s*(.-)%s*$", "%1") + if #str > 0 then + t[#t+1] = { code = str } + end + return t +end + +--[[ldx-- +We will tag keywords so that we can higlight them using a special font +or color. Users can extend this list when needed. +--ldx]]-- + +ldx.keywords = { } + +--[[ldx-- +Here come the reserved words: +--ldx]]-- + +ldx.keywords.reserved = { + ["and"] = 1, + ["break"] = 1, + ["do"] = 1, + ["else"] = 1, + ["elseif"] = 1, + ["end"] = 1, + ["false"] = 1, + ["for"] = 1, + ["function"] = 1, + ["if"] = 1, + ["in"] = 1, + ["local"] = 1, + ["nil"] = 1, + ["not"] = 1, + ["or"] = 1, + ["repeat"] = 1, + ["return"] = 1, + ["then"] = 1, + ["true"] = 1, + ["until"] = 1, + ["while"] = 1 +} + +--[[ldx-- +We need to escape a few tokens. We keep the hash local to the +definition but set it up only once, hence the do +construction. +--ldx]]-- + +do + local e = { [">"] = ">", ["<"] = "<", ["&"] = "&" } + function ldx.escape(str) + return (str:gsub("([><&])",e)) + end +end + +--[[ldx-- +Enhancing the code is a bit tricky due to the fact that we have to +deal with strings and escaped quotes within these strings. Before we +mess around with the code, we hide the strings, and after that we +insert them again. Single and double quoted strings are tagged so +that we can use a different font to highlight them. +--ldx]]-- + +ldx.make_index = true + +function ldx.enhance(data) -- i need to use lpeg and then we can properly autoindent -) + local e = ldx.escape + for k=1,#data do + local v = data[k] + if v.code then + local dqs, sqs, com, cmt, cod = { }, { }, { }, { }, e(v.code) + cod = cod:gsub('\\"', "##d##") + cod = cod:gsub("\\'", "##s##") + cod = cod:gsub("%-%-%[%[.-%]%]%-%-", function(s) + cmt[#cmt+1] = s + return ">>l>" + end) + cod = cod:gsub("%-%-([^\n]*)", function(s) + com[#com+1] = s + return ">>c>" + end) + cod = cod:gsub("(%b\"\")", function(s) + dqs[#dqs+1] = s:sub(2,-2) or "" + return ">>d>" + end) + cod = cod:gsub("(%b\'\')", function(s) + sqs[#sqs+1] = s:sub(2,-2) or "" + return ">>s>" + end) + cod = cod:gsub("(%a+)",function(key) + local class = ldx.keywords.reserved[key] + if class then + return "" .. key .. "" + else + return key + end + end) + cod = cod:gsub(">>s>", function(s) + return "" .. sqs[tonumber(s)] .. "" + end) + cod = cod:gsub(">>d>", function(s) + return "" .. dqs[tonumber(s)] .. "" + end) + cod = cod:gsub(">>c>", function(s) + return "" .. com[tonumber(s)] .. "" + end) + cod = cod:gsub(">>l>", function(s) + return cmt[tonumber(s)] + end) + cod = cod:gsub("##d##", "\\\"") + cod = cod:gsub("##s##", "\\\'") + if ldx.make_index then + local lines = cod:split("\n") + local f = "(function)%s+([%w%.]+)%s*%(" + for k=1,#lines do + local v = lines[k] + -- functies + v = v:gsub(f,function(key, str) + return "" .. str .. "(" + end) + -- variables + v = v:gsub("^([%w][%w%,%s]-)(=[^=])",function(str, rest) + local t = string.split(str, ",%s*") + for k=1,#t do + t[k] = "" .. t[k] .. "" + end + return table.concat(t,", ") .. rest + end) + -- so far + lines[k] = v + end + v.code = table.concat(lines,"\n") + else + v.code = cod + end + end + end +end + +--[[ldx-- +We're now ready to save the file in format. This boils +down to wrapping the code and comment as well as the whole document. We tag +lines in the code as such so that we don't need messy CDATA constructs +and by calculating the indentation we also avoid space troubles. It also makes +it possible to change the indentation afterwards. +--ldx]]-- + +function ldx.as_xml(data) -- ldx: not needed + local t, cmode = { }, false + t[#t+1] = "\n" + t[#t+1] = "\n\n" + for k=1,#data do + local v = data[k] + if v.code and not v.code:is_empty() then + t[#t+1] = "\n\n" + local split = v.code:split("\n") + for k=1,#split do -- make this faster + local v = split[k] + local a, b = v:find("^(%s+)") + if v then v = v:gsub("[\n\r ]+$","") end + if a and b then + v = v:sub(b+1,#v) + if cmode then + t[#t+1] = "" .. v .. "\n" + else + t[#t+1] = "" .. v .. "\n" + end + elseif v:is_empty() then + if cmode then + t[#t+1] = "\n" + else + t[#t+1] = "\n" + end + elseif v:find("^%-%-%[%[") then + t[#t+1] = "" .. v .. "\n" + cmode= true + elseif v:find("^%]%]%-%-") then + t[#t+1] = "" .. v .. "\n" + cmode= false + elseif cmode then + t[#t+1] = "" .. v .. "\n" + else + t[#t+1] = "" .. v .. "\n" + end + end + t[#t+1] = "\n" + elseif v.comment then + t[#t+1] = "\n\n" .. v.comment .. "\n\n" + else + -- cannot happen + end + end + t[#t+1] = "\n\n" + return table.concat(t,"") +end + +--[[ldx-- +Saving the result is a trivial effort. +--ldx]]-- + +function ldx.save(filename,data) + file.savedata(filename,ldx.as_xml(data)) +end + +--[[ldx-- +The next function wraps it all in one call: +--ldx]]-- + +function ldx.convert(luaname,ldxname) + if not file.is_readable(luaname) then + luaname = luaname .. ".lua" + end + if file.is_readable(luaname) then + if not ldxname then + ldxname = file.replacesuffix(luaname,"ldx") + end + local data = ldx.load(luaname) + if data then + ldx.enhance(data) + if ldxname ~= luaname then + ldx.save(ldxname,data) + end + end + end +end + +--[[ldx-- +This module can be used directly: + + +mtxrun --internal x-ldx somefile.lua + + +will produce an ldx file that can be processed with +by running: + + +texexec --use=x-ldx --forcexml somefile.ldx + + +You can do this in one step by saying: + + +texmfstart texexec --ctx=x-ldx somefile.lua + + +This will trigger into loading the mentioned + file. That file describes the conversion as well +as the module to be used. + +The main conversion call is: +--ldx]]-- + +-- todo: assume usage of "mtxrun --script x-ldx", maybe make it mtx-ldx + +if arg and arg[1] then + ldx.convert(arg[1],arg[2]) +end + +--~ exit(1) diff --git a/tex/context/base/x-ldx.mkiv b/tex/context/base/x-ldx.mkiv new file mode 100644 index 000000000..bf9bdf71a --- /dev/null +++ b/tex/context/base/x-ldx.mkiv @@ -0,0 +1,186 @@ +\setupxml[default=hidden] + +\usemodule[x][mathml] +\usemodule[abr-02] + +\xmlregisterdocumentsetup{ldx}{xml:mml:define} +\xmlregisterdocumentsetup{ldx}{xml:ldx:define} + +\xmlregisterns{ldx}{ldx} + +\startxmlsetups xml:ldx:define +% \xmlgrab {\xmldocument} {ldx:*} {*} + \xmlsetsetup {#1} {ldx:*} {ldx:*} +\stopxmlsetups + +% % % + +\startxmlsetups ldx:p + \xmlflush{#1}\par +\stopxmlsetups + +\startxmlsetups ldx:source + \source{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups ldx:key + \dontleavehmode{\bf\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups ldx:variable + \xmlflush{#1} +% \expanded{\variable{\xmlflush{#1}}} +\stopxmlsetups + +\startxmlsetups ldx:function + \dontleavehmode{\bf function}\space\xmlflush{#1} +% \expanded{\function{\xmlflush{#1}}} +\stopxmlsetups + +\startxmlsetups ldx:com + \dontleavehmode{\tt--\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups ldx:document + \page + \xmlflush{#1} + \determineregistercharacteristics[function] + \startmode[*register] + \testpage[4] + \extra{Functions} + \placeregister[function] + \stopmode + \determineregistercharacteristics[variable] + \startmode[*register] + \testpage[4] + \extra{Variables} + \placeregister[variable] + \stopmode +\stopxmlsetups + +\newcounter\CommentCounter + +\startxmlsetups ldx:comment + \blank + \doglobal\increment\CommentCounter + \margintitle{\bf\CommentCounter} + \xmlflush{#1} + \blank +\stopxmlsetups + +\startxmlsetups ldx:dqs + \dontleavehmode\bgroup\tt"\xmlflush{#1}"\egroup +\stopxmlsetups + +\startxmlsetups ldx:sqs + \dontleavehmode\bgroup\tt'\xmlflush{#1}'\egroup +\stopxmlsetups + +\startxmlsetups ldx:code + \startpacked + \xmlflush{#1}\relax + \stoppacked +\stopxmlsetups + +\startxmlsetups ldx:lines + \startpacked + \xmlflush{#1} + \stoppacked +\stopxmlsetups + +\startxmlsetups ldx:line + \doifelsenothing {\xmlflush{#1}} { + \xmlflush{#1}\crlf + } { + \dontleavehmode \hbox to \hsize \bgroup + \strut + \hskip.25\dimexpr\xmlattdef{#1}{n}{0}em\relax\relax % extra relax needed ! + \doif {\xmlatt{#1}{comment}} {yes} {\tt} + \xmlflush{#1} + \hss + \egroup + \endgraf + } +\stopxmlsetups + +\startxmlsetups ldx:logo + \uppercasestring\xmlatt{#1}{label}\xmlatt{#1}{name}\to\ascii + \ifx\ascii\empty\else\getvalue{\ascii}\fi +\stopxmlsetups + +\startxmlsetups ldx:l + \uppercasestring\xmlatt{#1}{l}\xmlatt{#1}{n}\to\ascii + \ifx\ascii\empty\else\getvalue{\ascii}\fi +\stopxmlsetups + +\startxmlsetups ldx:typing + \blank + \startpacked \tt + \xmlverbatim{#1} + \stoppacked + \blank +\stopxmlsetups + +\startxmlsetups ldx:type + \dontleavehmode{\tt\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups ldx:t + \dontleavehmode{\tt\xmlflush{#1}} +\stopxmlsetups + +% + +\def\xmldocument{ldx} + +% key -> kw +% dqs -> dq +% sqs -> sq +% line -> ln +% code -> cd +% comment -> tx (text) + +\definetypeface[mainfacenormal] [ss][sans] [iwona] [default] +\definetypeface[mainfacenormal] [rm][serif][palatino] [default] +\definetypeface[mainfacenormal] [tt][mono] [modern] [default][rscale=1] % 1.1 +\definetypeface[mainfacenormal] [mm][math] [iwona] [default][encoding=default] + +\definetypeface[mainfacemedium] [ss][sans] [iwona-medium][default] +\definetypeface[mainfacenormal] [rm][serif][palatino] [default] +\definetypeface[mainfacemedium] [tt][mono] [modern] [default][rscale=1] % 1.1 +\definetypeface[mainfacemedium] [mm][math] [iwona-medium][default][encoding=default] + +\definetypeface[mainfacenarrowtt][tt][mono] [modern-cond] [default][rscale=1] % 1.1 + +\setupbodyfont + [mainfacenormal,11pt] + +\setupwhitespace + [big] + +\defineregister[function][functions] +\defineregister[variable][variables] + +\definehead[source][subject] +\definehead[extra] [subsubject] +\definehead[topic] [subsubsubject] + +\setuphead + [source] + [style=\bfb] + +\setuphead + [extra] + [style=\bfa] + +\setuphead + [topic] + [style=\bf] + +\setuplayout + [width=middle, + height=middle, + backspace=2cm, + topspace=2cm] + +\endinput diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index 840e64e4a..dbd25af37 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 03/26/11 11:35:06 +-- merge date : 03/26/11 12:41:29 do -- begin closure to overcome local limits and interference @@ -3920,16 +3920,14 @@ a helper function.

function constructors.checkedfeatures(what,features) if features and next(features) then - local done = false for key, value in next, handlers[what].features.defaults do if features[key] == nil then features[key] = value - done = true end end - return features, done -- done signals a change + return features else - return fastcopy(defaults), true + return fastcopy(defaults) end end @@ -3942,9 +3940,11 @@ function constructors.initializefeatures(what,tfmdata,features,trace,report) local whatfeatures = whathandler.features local whatinitializers = whatfeatures.initializers local whatmodechecker = whatfeatures.modechecker - local mode = properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features)) or features.mode or "base" - properties.mode = mode -- also status - local done = { } + -- properties.mode can be enforces (for instance in font-otd) + local mode = properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" + properties.mode = mode -- also status + -- + local done = { } while true do local redo = false local initializers = whatfeatures.initializers[mode] @@ -3965,8 +3965,13 @@ function constructors.initializefeatures(what,tfmdata,features,trace,report) end action(tfmdata,value,features) -- can set mode (e.g. goodies) so it can trigger a restart if mode ~= properties.mode then - mode = properties.mode - redo = true + if whatmodechecker then + properties.mode = whatmodechecker(tfmdata,features,properties.mode) -- force checking + end + if mode ~= properties.mode then + mode = properties.mode + redo = true + end end done[feature] = true end -- cgit v1.2.3