diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/trac-vis.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/trac-vis.lua | 427 |
1 files changed, 241 insertions, 186 deletions
diff --git a/Master/texmf-dist/tex/context/base/trac-vis.lua b/Master/texmf-dist/tex/context/base/trac-vis.lua index df4909c3ef6..eb5373ee350 100644 --- a/Master/texmf-dist/tex/context/base/trac-vis.lua +++ b/Master/texmf-dist/tex/context/base/trac-vis.lua @@ -32,18 +32,19 @@ local formatters = string.formatters -- todo: global switch (so no attributes) -- todo: maybe also xoffset, yoffset of glyph -- todo: inline concat (more efficient) +-- todo: tags can also be numbers (just add to hash) local nodecodes = nodes.nodecodes local disc_code = nodecodes.disc local kern_code = nodecodes.kern local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local glue_code = nodecodes.glue local penalty_code = nodecodes.penalty local whatsit_code = nodecodes.whatsit local user_code = nodecodes.user +local math_code = nodecodes.math local gluespec_code = nodecodes.gluespec local kerncodes = nodes.kerncodes @@ -59,32 +60,54 @@ local leftskip_code = gluecodes.leftskip local rightskip_code = gluecodes.rightskip local whatsitcodes = nodes.whatsitcodes +local mathcodes = nodes.mathcodes + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode + +local getfield = nuts.getfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local setfield = nuts.setfield +local getattr = nuts.getattr +local setattr = nuts.setattr +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getchar = nuts.getchar +local getbox = nuts.getbox +local getlist = nuts.getlist +local getleader = nuts.getleader + +local hpack_nodes = nuts.hpack +local vpack_nodes = nuts.vpack +local copy_node = nuts.copy +local copy_list = nuts.copy_list +local free_node = nuts.free +local free_node_list = nuts.flush_list +local insert_node_before = nuts.insert_before +local insert_node_after = nuts.insert_after +local traverse_nodes = nuts.traverse +local linked_nodes = nuts.linked + +local fast_hpack = nuts.fasthpack +local fast_hpack_string = nuts.typesetters.fast_hpack + +local texgetattribute = tex.getattribute +local texsetattribute = tex.setattribute -local concat_nodes = nodes.concat -local hpack_nodes = node.hpack -local vpack_nodes = node.vpack -local hpack_string = typesetters.hpack -local fast_hpack_string = typesetters.fast_hpack -local copy_node = node.copy -local copy_list = node.copy_list -local free_node = node.free -local free_node_list = node.flush_list -local insert_node_before = node.insert_before -local insert_node_after = node.insert_after -local fast_hpack = nodes.fasthpack -local traverse_nodes = node.traverse - -local tex_attribute = tex.attribute -local tex_box = tex.box local unsetvalue = attributes.unsetvalue local current_font = font.current -local exheights = fonts.hashes.exheights -local emwidths = fonts.hashes.emwidths +local fonthashes = fonts.hashes +local chardata = fonthashes.characters +local exheights = fonthashes.exheights +local emwidths = fonthashes.emwidths local pt_factor = number.dimenfactors.pt -local nodepool = nodes.pool +local nodepool = nuts.pool local new_rule = nodepool.rule local new_kern = nodepool.kern local new_glue = nodepool.glue @@ -120,6 +143,7 @@ local trace_fontkern local trace_strut local trace_whatsit local trace_user +local trace_math local report_visualize = logs.reporter("visualize") @@ -139,26 +163,27 @@ local modes = { simplevbox = 1024 + 2, simplevtop = 1024 + 4, user = 2048, + math = 4096, } local modes_makeup = { "hbox", "vbox", "kern", "glue", "penalty" } local modes_boxes = { "hbox", "vbox" } -local modes_all = { "hbox", "vbox", "kern", "glue", "penalty", "fontkern", "whatsit", "glyph", "user" } +local modes_all = { "hbox", "vbox", "kern", "glue", "penalty", "fontkern", "whatsit", "glyph", "user", "math" } local usedfont, exheight, emwidth -local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user +local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math local enabled = false local layers = { } local preset_boxes = modes.hbox + modes.vbox local preset_makeup = preset_boxes + modes.kern + modes.glue + modes.penalty -local preset_all = preset_makeup + modes.fontkern + modes.whatsit + modes.glyph + modes.user +local preset_all = preset_makeup + modes.fontkern + modes.whatsit + modes.glyph + modes.user + modes.math function visualizers.setfont(id) usedfont = id or current_font() exheight = exheights[usedfont] - emwidth = emwidths[usedfont] + emwidth = emwidths[usedfont] end -- we can preset a bunch of bits @@ -190,6 +215,7 @@ local function enable() l_whatsit = layers.whatsit l_glyph = layers.glyph l_user = layers.user + l_math = layers.math nodes.tasks.enableaction("shipouts","nodes.visualizers.handler") report_visualize("enabled") enabled = true @@ -204,18 +230,12 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha a = preset_makeup else a = setbit(a,preset_makeup) - -- for i=1,#modes_makeup do - -- a = setvisual(modes_makeup[i],a) - -- end end elseif n == "boxes" then if not a or a == 0 or a == unsetvalue then a = preset_boxes else a = setbit(a,preset_boxes) - -- for i=1,#modes_boxes do - -- a = setvisual(modes_boxes[i],a) - -- end end elseif n == "all" then if what == false then @@ -224,9 +244,6 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha a = preset_all else a = setbit(a,preset_all) - -- for i=1,#modes_all do - -- a = setvisual(modes_all[i],a) - -- end end else local m = modes[n] @@ -256,11 +273,11 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha end function visualizers.setvisual(n) - tex_attribute[a_visual] = setvisual(n,tex_attribute[a_visual]) + texsetattribute(a_visual,setvisual(n,texgetattribute(a_visual))) end function visualizers.setlayer(n) - tex_attribute[a_layer] = layers[n] or unsetvalue + texsetattribute(a_layer,layers[n] or unsetvalue) end commands.setvisual = visualizers.setvisual @@ -271,7 +288,7 @@ function commands.visual(n) end local function set(mode,v) - tex_attribute[a_visual] = setvisual(mode,tex_attribute[a_visual],v) + texsetattribute(a_visual,setvisual(mode,texgetattribute(a_visual),v)) end for mode, value in next, modes do @@ -292,6 +309,7 @@ local c_skip_a = "trace:c" local c_skip_b = "trace:m" local c_glyph = "trace:o" local c_white = "trace:w" +local c_math = "trace:r" local c_positive_d = "trace:db" local c_negative_d = "trace:dr" @@ -302,46 +320,43 @@ local c_skip_a_d = "trace:dc" local c_skip_b_d = "trace:dm" local c_glyph_d = "trace:do" local c_white_d = "trace:dw" +local c_math_d = "trace:dr" local function sometext(str,layer,color,textcolor) -- we can just paste verbatim together .. no typesteting needed local text = fast_hpack_string(str,usedfont) - local size = text.width + local size = getfield(text,"width") local rule = new_rule(size,2*exheight,exheight/2) local kern = new_kern(-size) if color then setcolor(rule,color) end if textcolor then - setlistcolor(text.list,textcolor) + setlistcolor(getlist(text),textcolor) end - local info = concat_nodes { - rule, - kern, - text, - } + local info = linked_nodes(rule,kern,text) setlisttransparency(info,c_zero) info = fast_hpack(info) if layer then - info[a_layer] = layer + setattr(info,a_layer,layer) end - local width = info.width - info.width = 0 - info.height = 0 - info.depth = 0 + local width = getfield(info,"width") + setfield(info,"width",0) + setfield(info,"height",0) + setfield(info,"depth",0) return info, width end local f_cache = { } local function fontkern(head,current) - local kern = current.kern + local kern = getfield(current,"kern") local info = f_cache[kern] if info then -- print("hit fontkern") else local text = fast_hpack_string(formatters[" %0.3f"](kern*pt_factor),usedfont) local rule = new_rule(emwidth/10,6*exheight,2*exheight) - local list = text.list + local list = getlist(text) if kern > 0 then setlistcolor(list,c_positive_d) elseif kern < 0 then @@ -351,16 +366,12 @@ local function fontkern(head,current) end setlisttransparency(list,c_text_d) settransparency(rule,c_text_d) - text.shift = -5 * exheight - info = concat_nodes { - rule, - text, - } - info = fast_hpack(info) - info[a_layer] = l_fontkern - info.width = 0 - info.height = 0 - info.depth = 0 + setfield(text,"shift",-5 * exheight) + info = fast_hpack(linked_nodes(rule,text)) + setattr(info,a_layer,l_fontkern) + setfield(info,"width",0) + setfield(info,"height",0) + setfield(info,"depth",0) f_cache[kern] = info end head = insert_node_before(head,current,copy_list(info)) @@ -368,8 +379,7 @@ local function fontkern(head,current) end local w_cache = { } - -local tags = { +local tags = { open = "FIC", write = "FIW", close = "FIC", @@ -401,7 +411,7 @@ local tags = { } local function whatsit(head,current) - local what = current.subtype + local what = getsubtype(current) local info = w_cache[what] if info then -- print("hit whatsit") @@ -409,22 +419,45 @@ local function whatsit(head,current) local tag = whatsitcodes[what] -- maybe different text colors per tag info = sometext(formatters["W:%s"](tag and tags[tag] or what),usedfont,nil,c_white) - info[a_layer] = l_whatsit + setattr(info,a_layer,l_whatsit) w_cache[what] = info end head, current = insert_node_after(head,current,copy_list(info)) return head, current end +local u_cache = { } + local function user(head,current) - local what = current.subtype - local info = w_cache[what] + local what = getsubtype(current) + local info = u_cache[what] if info then -- print("hit user") else info = sometext(formatters["U:%s"](what),usedfont) - info[a_layer] = l_user - w_cache[what] = info + setattr(info,a_layer,l_user) + u_cache[what] = info + end + head, current = insert_node_after(head,current,copy_list(info)) + return head, current +end + +local m_cache = { } +local tags = { + beginmath = "B", + endmath = "E", +} + +local function math(head,current) + local what = getsubtype(current) + local info = m_cache[what] + if info then + -- print("hit math") + else + local tag = mathcodes[what] + info = sometext(formatters["M:%s"](tag and tags[tag] or what),usedfont,nil,c_math_d) + setattr(info,a_layer,l_math) + m_cache[what] = info end head, current = insert_node_after(head,current,copy_list(info)) return head, current @@ -432,12 +465,15 @@ end local b_cache = { } -local function ruledbox(head,current,vertical,layer,what,simple) - local wd = current.width +local function ruledbox(head,current,vertical,layer,what,simple,previous) + local wd = getfield(current,"width") if wd ~= 0 then - local ht, dp = current.height, current.depth - local next, prev = current.next, current.prev - current.next, current.prev = nil, nil + local ht = getfield(current,"height") + local dp = getfield(current,"depth") + local next = getnext(current) + local prev = previous -- getprev(current) ... prev can be wrong in math mode < 0.78.3 + setfield(current,"next",nil) + setfield(current,"prev",nil) local linewidth = emwidth/10 local baseline, baseskip if dp ~= 0 and ht ~= 0 then @@ -446,19 +482,16 @@ local function ruledbox(head,current,vertical,layer,what,simple) if not baseline then -- due to an optimized leader color/transparency we need to set the glue node in order -- to trigger this mechanism - local leader = concat_nodes { - new_glue(2*linewidth), -- 2.5 - new_rule(6*linewidth,linewidth,0), -- 5.0 - new_glue(2*linewidth), -- 2.5 - } + local leader = linked_nodes(new_glue(2*linewidth),new_rule(6*linewidth,linewidth,0),new_glue(2*linewidth)) -- setlisttransparency(leader,c_text) leader = fast_hpack(leader) -- setlisttransparency(leader,c_text) baseline = new_glue(0) - baseline.leader = leader - baseline.subtype = cleaders_code - baseline.spec.stretch = 65536 - baseline.spec.stretch_order = 2 + setfield(baseline,"leader",leader) + setfield(baseline,"subtype",cleaders_code) + local spec = getfield(baseline,"spec") + setfield(spec,"stretch",65536) + setfield(spec,"stretch_order",2) setlisttransparency(baseline,c_text) b_cache.baseline = baseline end @@ -480,54 +513,50 @@ local function ruledbox(head,current,vertical,layer,what,simple) this = b_cache[what] if not this then local text = fast_hpack_string(what,usedfont) - this = concat_nodes { - new_kern(-text.width), - text, - } + this = linked_nodes(new_kern(-getfield(text,"width")),text) setlisttransparency(this,c_text) this = fast_hpack(this) - this.width = 0 - this.height = 0 - this.depth = 0 + setfield(this,"width",0) + setfield(this,"height",0) + setfield(this,"depth",0) b_cache[what] = this end end - local info = concat_nodes { - this and copy_list(this) or nil, -- this also triggers the right mode (else sometimes no whatits) + -- we need to trigger the right mode (else sometimes no whatits) + local info = linked_nodes( + this and copy_list(this) or nil, new_rule(linewidth,ht,dp), new_rule(wd-2*linewidth,-dp+linewidth,dp), new_rule(linewidth,ht,dp), new_kern(-wd+linewidth), - new_rule(wd-2*linewidth,ht,-ht+linewidth), - baseskip, - baseline, - } + new_rule(wd-2*linewidth,ht,-ht+linewidth) + ) + if baseskip then + info = linked_nodes(info,baseskip,baseline) + end setlisttransparency(info,c_text) info = fast_hpack(info) - info.width = 0 - info.height = 0 - info.depth = 0 - info[a_layer] = layer - local info = concat_nodes { - current, - new_kern(-wd), - info, - } + setfield(info,"width",0) + setfield(info,"height",0) + setfield(info,"depth",0) + setattr(info,a_layer,layer) + local info = linked_nodes(current,new_kern(-wd),info) info = fast_hpack(info,wd) if vertical then info = vpack_nodes(info) end if next then - info.next = next - next.prev = info + setfield(info,"next",next) + setfield(next,"prev",info) end if prev then -if prev.id == gluespec_code then - -- weird, how can this happen, an inline glue-spec -else - info.prev = prev - prev.next = info -end + if getid(prev) == gluespec_code then + report_visualize("ignoring invalid prev") + -- weird, how can this happen, an inline glue-spec, probably math + else + setfield(info,"prev",prev) + setfield(prev,"next",info) + end end if head == current then return info, info @@ -539,48 +568,49 @@ end end end -local function ruledglyph(head,current) - local wd = current.width +local function ruledglyph(head,current,previous) + local wd = getfield(current,"width") + -- local wd = chardata[getfield(current,"font")][getfield(current,"char")].width if wd ~= 0 then - local ht, dp = current.height, current.depth - local next, prev = current.next, current.prev - current.next, current.prev = nil, nil + local ht = getfield(current,"height") + local dp = getfield(current,"depth") + local next = getnext(current) + local prev = previous + setfield(current,"next",nil) + setfield(current,"prev",nil) local linewidth = emwidth/20 local baseline if dp ~= 0 and ht ~= 0 then baseline = new_rule(wd-2*linewidth,linewidth,0) end local doublelinewidth = 2*linewidth - local info = concat_nodes { + -- could be a pdf rule + local info = linked_nodes( new_rule(linewidth,ht,dp), new_rule(wd-doublelinewidth,-dp+linewidth,dp), new_rule(linewidth,ht,dp), new_kern(-wd+linewidth), new_rule(wd-doublelinewidth,ht,-ht+linewidth), new_kern(-wd+doublelinewidth), - baseline, - } + baseline + ) setlistcolor(info,c_glyph) setlisttransparency(info,c_glyph_d) info = fast_hpack(info) - info.width = 0 - info.height = 0 - info.depth = 0 - info[a_layer] = l_glyph - local info = concat_nodes { - current, - new_kern(-wd), - info, - } + setfield(info,"width",0) + setfield(info,"height",0) + setfield(info,"depth",0) + setattr(info,a_layer,l_glyph) + local info = linked_nodes(current,new_kern(-wd),info) info = fast_hpack(info) - info.width = wd + setfield(info,"width",wd) if next then - info.next = next - next.prev = info + setfield(info,"next",next) + setfield(next,"prev",info) end if prev then - info.prev = prev - prev.next = info + setfield(info,"prev",prev) + setfield(prev,"next",info) end if head == current then return info, info @@ -622,10 +652,12 @@ local tags = { -- false = "HS", } +-- we sometimes pass previous as we can have issues in math (not watertight for all) + local function ruledglue(head,current,vertical) - local spec = current.spec - local width = spec.width - local subtype = current.subtype + local spec = getfield(current,"spec") + local width = getfield(spec,"width") + local subtype = getsubtype(current) local amount = formatters["%s:%0.3f"](tags[subtype] or (vertical and "VS") or "HS",width*pt_factor) local info = g_cache[amount] if info then @@ -653,13 +685,13 @@ local function ruledglue(head,current,vertical) info = vpack_nodes(info) end head, current = insert_node_before(head,current,info) - return head, current.next + return head, getnext(current) end local k_cache = { } local function ruledkern(head,current,vertical) - local kern = current.kern + local kern = getfield(current,"kern") local info = k_cache[kern] if info then -- print("kern hit") @@ -679,13 +711,13 @@ local function ruledkern(head,current,vertical) info = vpack_nodes(info) end head, current = insert_node_before(head,current,info) - return head, current.next + return head, getnext(current) end local p_cache = { } local function ruledpenalty(head,current,vertical) - local penalty = current.penalty + local penalty = getfield(current,"penalty") local info = p_cache[penalty] if info then -- print("penalty hit") @@ -705,7 +737,7 @@ local function ruledpenalty(head,current,vertical) info = vpack_nodes(info) end head, current = insert_node_before(head,current,info) - return head, current.next + return head, getnext(current) end local function visualize(head,vertical) @@ -721,12 +753,14 @@ local function visualize(head,vertical) local trace_glyph = false local trace_simple = false local trace_user = false - local current = head + local trace_math = false + local current = head + local previous = nil + local attr = unsetvalue local prev_trace_fontkern = nil - local attr = unsetvalue while current do - local id = current.id - local a = current[a_visual] or unsetvalue + local id = getid(current) + local a = getattr(current,a_visual) or unsetvalue if a ~= attr then prev_trace_fontkern = trace_fontkern if a == unsetvalue then @@ -742,6 +776,7 @@ local function visualize(head,vertical) trace_glyph = false trace_simple = false trace_user = false + trace_math = false else -- dead slow: trace_hbox = hasbit(a, 1) trace_vbox = hasbit(a, 2) @@ -755,34 +790,35 @@ local function visualize(head,vertical) trace_glyph = hasbit(a, 512) trace_simple = hasbit(a,1024) trace_user = hasbit(a,2048) + trace_math = hasbit(a,4096) end attr = a end if trace_strut then - current[a_layer] = l_strut + setattr(current,a_layer,l_strut) elseif id == glyph_code then if trace_glyph then - head, current = ruledglyph(head,current) + head, current = ruledglyph(head,current,previous) end elseif id == disc_code then if trace_glyph then - local pre = current.pre + local pre = getfield(current,"pre") if pre then - current.pre = ruledglyph(pre,pre) + setfield(current,"pre",ruledglyph(pre,pre)) end - local post = current.post + local post = getfield(current,"post") if post then - current.post = ruledglyph(post,post) + setfield(current,"post",ruledglyph(post,post)) end - local replace = current.replace + local replace = getfield(current,"replace") if replace then - current.replace = ruledglyph(replace,replace) + setfield(current,"replace",ruledglyph(replace,replace)) end end elseif id == kern_code then - local subtype = current.subtype + local subtype = getsubtype(current) -- tricky ... we don't copy the trace attribute in node-inj (yet) - if subtype == font_kern_code or current[a_fontkern] then + if subtype == font_kern_code or getattr(current,a_fontkern) then if trace_fontkern or prev_trace_fontkern then head, current = fontkern(head,current) end @@ -792,9 +828,9 @@ local function visualize(head,vertical) end end elseif id == glue_code then - local content = current.leader + local content = getleader(current) if content then - current.leader = visualize(content,false) + setfield(current,"leader",visualize(content,false)) elseif trace_glue then head, current = ruledglue(head,current,vertical) end @@ -803,37 +839,42 @@ local function visualize(head,vertical) head, current = ruledpenalty(head,current,vertical) end elseif id == disc_code then - current.pre = visualize(current.pre) - current.post = visualize(current.post) - current.replace = visualize(current.replace) + setfield(current,"pre",visualize(getfield(current,"pre"))) + setfield(current,"post",isualize(getfield(current,"post"))) + setfield(current,"replace",visualize(getfield(current,"replace"))) elseif id == hlist_code then - local content = current.list + local content = getlist(current) if content then - current.list = visualize(content,false) + setfield(current,"list",visualize(content,false)) end if trace_hbox then - head, current = ruledbox(head,current,false,l_hbox,"H__",trace_simple) + head, current = ruledbox(head,current,false,l_hbox,"H__",trace_simple,previous) end elseif id == vlist_code then - local content = current.list + local content = getlist(current) if content then - current.list = visualize(content,true) + setfield(current,"list",visualize(content,true)) end if trace_vtop then - head, current = ruledbox(head,current,true,l_vtop,"_T_",trace_simple) + head, current = ruledbox(head,current,true,l_vtop,"_T_",trace_simple,previous) elseif trace_vbox then - head, current = ruledbox(head,current,true,l_vbox,"__V",trace_simple) + head, current = ruledbox(head,current,true,l_vbox,"__V",trace_simple,previous) end elseif id == whatsit_code then if trace_whatsit then head, current = whatsit(head,current) end elseif id == user_code then - if trace_whatsit then + if trace_user then head, current = user(head,current) end + elseif id == math_code then + if trace_math then + head, current = math(head,current) + end end - current = current.next + previous = current + current = getnext(current) end return head end @@ -859,27 +900,39 @@ local function cleanup() nk, k_cache = freed(k_cache) nw, w_cache = freed(w_cache) nb, b_cache = freed(b_cache) - -- report_visualize("cache: %s fontkerns, %s skips, %s penalties, %s kerns, %s whatsits, %s boxes",nf,ng,np,nk,nw,nb) + -- report_visualize("cache cleanup: %s fontkerns, %s skips, %s penalties, %s kerns, %s whatsits, %s boxes",nf,ng,np,nk,nw,nb) end -function visualizers.handler(head) +local function handler(head) if usedfont then starttiming(visualizers) - -- local l = tex_attribute[a_layer] - -- local v = tex_attribute[a_visual] - -- tex_attribute[a_layer] = unsetvalue - -- tex_attribute[a_visual] = unsetvalue - head = visualize(head) - -- tex_attribute[a_layer] = l - -- tex_attribute[a_visual] = v + -- local l = texgetattribute(a_layer) + -- local v = texgetattribute(a_visual) + -- texsetattribute(a_layer,unsetvalue) + -- texsetattribute(a_visual,unsetvalue) + head = visualize(tonut(head)) + -- texsetattribute(a_layer,l) + -- texsetattribute(a_visual,v) -- -- cleanup() stoptiming(visualizers) + return tonode(head), true + else + return head, false end - return head, false end +visualizers.handler = handler + function visualizers.box(n) - tex_box[n].list = visualizers.handler(tex_box[n].list) + if usedfont then + starttiming(visualizers) + local box = getbox(n) + setfield(box,"list",visualize(getlist(box))) + stoptiming(visualizers) + return head, true + else + return head, false + end end local last = nil @@ -893,9 +946,9 @@ local mark = { local function markfonts(list) for n in traverse_nodes(list) do - local id = n.id + local id = getid(n) if id == glyph_code then - local font = n.font + local font = getfont(n) local okay = used[font] if not okay then last = last + 1 @@ -904,23 +957,25 @@ local function markfonts(list) end setcolor(n,okay) elseif id == hlist_code or id == vlist_code then - markfonts(n.list) + markfonts(getlist(n)) end end end function visualizers.markfonts(list) last, used = 0, { } - markfonts(type(n) == "number" and tex_box[n].list or n) + markfonts(type(n) == "number" and getlist(getbox(n)) or n) end function commands.markfonts(n) visualizers.markfonts(n) end +luatex.registerstopactions(cleanup) + statistics.register("visualization time",function() if enabled then - cleanup() -- in case we don't don't do it each time + -- cleanup() -- in case we don't don't do it each time return format("%s seconds",statistics.elapsedtime(visualizers)) end end) |