diff options
Diffstat (limited to 'tex/context/base/node-tra.lua')
-rw-r--r-- | tex/context/base/node-tra.lua | 355 |
1 files changed, 137 insertions, 218 deletions
diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua index 081107277..9617f7476 100644 --- a/tex/context/base/node-tra.lua +++ b/tex/context/base/node-tra.lua @@ -34,30 +34,9 @@ nodes.handlers = handlers local injections = nodes.injections or { } nodes.injections = injections -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 getchar = nuts.getchar -local getsubtype = nuts.getsubtype -local getlist = nuts.getlist - -local setattr = nuts.setattr - -local flush_list = nuts.flush_list -local count_nodes = nuts.count -local used_nodes = nuts.usedlist - -local traverse_by_id = nuts.traverse_id -local traverse_nodes = nuts.traverse -local d_tostring = nuts.tostring - -local nutpool = nuts.pool -local new_rule = nutpool.rule +local traverse_nodes = node.traverse +local traverse_by_id = node.traverse_id +local count_nodes = nodes.count local nodecodes = nodes.nodecodes local whatcodes = nodes.whatcodes @@ -77,6 +56,9 @@ local gluespec_code = nodecodes.gluespec local localpar_code = whatcodes.localpar local dir_code = whatcodes.dir +local nodepool = nodes.pool +local new_rule = nodepool.rule + local dimenfactors = number.dimenfactors local formatters = string.formatters @@ -86,16 +68,15 @@ function nodes.showlist(head, message) if message then report_nodes(message) end - for n in traverse_nodes(tonut(head)) do - report_nodes(d_tostring(n)) + for n in traverse_nodes(head) do + report_nodes(tostring(n)) end end function nodes.handlers.checkglyphs(head,message) - local h = tonut(head) local t = { } - for g in traverse_by_id(glyph_code,h) do - t[#t+1] = formatters["%U:%s"](getchar(g),getsubtype(g)) + for g in traverse_by_id(glyph_code,head) do + t[#t+1] = formatters["%U:%s"](g.char,g.subtype) end if #t > 0 then if message and message ~= "" then @@ -109,12 +90,12 @@ end function nodes.handlers.checkforleaks(sparse) local l = { } - local q = used_nodes() - for p in traverse_nodes(q) do - local s = table.serialize(nodes.astable(p,sparse),nodecodes[getid(p)]) + local q = node.usedlist() + for p in traverse(q) do + local s = table.serialize(nodes.astable(p,sparse),nodecodes[p.id]) l[s] = (l[s] or 0) + 1 end - flush_list(q) + node.flush_list(q) for k, v in next, l do report_nodes("%s * %s",v,k) end @@ -124,40 +105,39 @@ local f_sequence = formatters["U+%04X:%s"] local function tosequence(start,stop,compact) if start then - start = tonut(start) - stop = stop and tonut(stop) local t = { } while start do - local id = getid(start) + local id = start.id if id == glyph_code then - local c = getchar(start) + local c = start.char if compact then - local components = getfield(start,"components") - if components then - t[#t+1] = tosequence(components,nil,compact) + if start.components then + t[#t+1] = tosequence(start.components,nil,compact) else t[#t+1] = utfchar(c) end else t[#t+1] = f_sequence(c,utfchar(c)) end + elseif id == whatsit_code and start.subtype == localpar_code or start.subtype == dir_code then + t[#t+1] = "[" .. start.dir .. "]" elseif id == rule_code then if compact then t[#t+1] = "|" else t[#t+1] = nodecodes[id] end - elseif id == whatsit_code and getsubtype(start) == localpar_code or getsubtype(start) == dir_code then - t[#t+1] = "[" .. getfield(start,"dir") .. "]" - elseif compact then - t[#t+1] = "[]" else - t[#t+1] = nodecodes[id] + if compact then + t[#t+1] = "[]" + else + t[#t+1] = nodecodes[id] + end end if start == stop then break else - start = getnext(start) + start = start.next end end if compact then @@ -173,23 +153,21 @@ end nodes.tosequence = tosequence function nodes.report(t,done) - report_nodes("output %a, %changed %a, %s nodes",status.output_active,done,count_nodes(tonut(t))) + report_nodes("output %a, %changed %a, %s nodes",status.output_active,done,count_nodes(t)) end function nodes.packlist(head) local t = { } - for n in traverse_nodes(tonut(head)) do - t[#t+1] = d_tostring(n) + for n in traverse(head) do + t[#t+1] = tostring(n) end return t end function nodes.idstostring(head,tail) - head = tonut(head) - tail = tail and tonut(tail) local t, last_id, last_n = { }, nil, 0 for n in traverse_nodes(head,tail) do -- hm, does not stop at tail - local id = getid(n) + local id = n.id if not last_id then last_id, last_n = id, 1 elseif last_id == id then @@ -217,8 +195,6 @@ function nodes.idstostring(head,tail) end -- function nodes.xidstostring(head,tail) -- only for special tracing of backlinks --- head = tonut(head) --- tail = tonut(tail) -- local n = head -- while n.next do -- n = n.next @@ -241,7 +217,7 @@ end -- if n == head then -- break -- end --- n = getprev(n) +-- n = n.prev -- end -- if not last_id then -- t[#t+1] = "no nodes" @@ -254,56 +230,51 @@ end -- end local function showsimplelist(h,depth,n) - h = h and tonut(h) while h do report_nodes("% w%s",n,d_tostring(h)) if not depth or n < depth then - local id = getid(h) + local id = h.id if id == hlist_code or id == vlist_code then - showsimplelist(getlist(h),depth,n+1) + showsimplelist(h.list,depth,n+1) end end - h = getnext(h) + h = h.next end end --- \startluacode --- callback.register('buildpage_filter',function() nodes.show_simple_list(tex.lists.contrib_head) end) --- \stopluacode --- \vbox{b\footnote{n}a} --- \startluacode --- callback.register('buildpage_filter',nil) --- \stopluacode +--~ \startluacode +--~ callback.register('buildpage_filter',function() nodes.show_simple_list(tex.lists.contrib_head) end) +--~ \stopluacode +--~ \vbox{b\footnote{n}a} +--~ \startluacode +--~ callback.register('buildpage_filter',nil) +--~ \stopluacode nodes.showsimplelist = function(h,depth) showsimplelist(h,depth,0) end local function listtoutf(h,joiner,textonly,last) + local joiner = (joiner == true and utfchar(0x200C)) or joiner -- zwnj local w = { } while h do - local id = getid(h) + local id = h.id if id == glyph_code then -- always true - local c = getchar(h) + local c = h.char w[#w+1] = c >= 0 and utfchar(c) or formatters["<%i>"](c) if joiner then w[#w+1] = joiner end elseif id == disc_code then - local pre = getfield(h,"pre") - local pos = getfield(h,"post") - local rep = getfield(h,"replace") + local pre = h.pre + local pos = h.post + local rep = h.replace w[#w+1] = formatters["[%s|%s|%s]"] ( pre and listtoutf(pre,joiner,textonly) or "", pos and listtoutf(pos,joiner,textonly) or "", rep and listtoutf(rep,joiner,textonly) or "" ) elseif textonly then - if id == glue_code then - local spec = getfield(h,"spec") - if spec and getfield(spec,"width") > 0 then - w[#w+1] = " " - end - elseif id == hlist_code or id == vlist_code then - w[#w+1] = "[]" + if id == glue_code and h.spec and h.spec.width > 0 then + w[#w+1] = " " end else w[#w+1] = "[-]" @@ -311,28 +282,24 @@ local function listtoutf(h,joiner,textonly,last) if h == last then break else - h = getnext(h) + h = h.next end end return concat(w) end -function nodes.listtoutf(h,joiner,textonly,last) - local joiner = joiner == true and utfchar(0x200C) or joiner -- zwnj - return listtoutf(tonut(h),joiner,textonly,last and tonut(last)) -end +nodes.listtoutf = listtoutf local what = { [0] = "unknown", "line", "box", "indent", "row", "cell" } local function showboxes(n,symbol,depth) - depth = depth or 0 - symbol = symbol or "." - for n in traverse_nodes(tonut(n)) do - local id = getid(n) + depth, symbol = depth or 0, symbol or "." + for n in traverse_nodes(n) do + local id = n.id if id == hlist_code or id == vlist_code then - local s = getsubtype(n) + local s = n.subtype report_nodes(rep(symbol,depth) .. what[s] or s) - showboxes(getlist(n),symbol,depth+1) + showboxes(n.list,symbol,depth+1) end end end @@ -355,8 +322,15 @@ local stripper = lpeg.patterns.stripzeros local dimenfactors = number.dimenfactors -local function nodetodimen(d,unit,fmt,strip) - d = tonut(d) -- tricky: direct nuts are an issue +local function numbertodimen(d,unit,fmt,strip) + if not d then + local str = formatters[fmt](0,unit) + return strip and lpegmatch(stripper,str) or str + end + local t = type(d) + if t == 'string' then + return d + end if unit == true then unit = "pt" fmt = "%0.5f%s" @@ -368,23 +342,27 @@ local function nodetodimen(d,unit,fmt,strip) fmt = "%0.5f%s" end end - local id = getid(d) + if t == "number" then + local str = formatters[fmt](d*dimenfactors[unit],unit) + return strip and lpegmatch(stripper,str) or str + end + local id = d.id if id == kern_code then - local str = formatters[fmt](getfield(d,"width")*dimenfactors[unit],unit) + local str = formatters[fmt](d.width*dimenfactors[unit],unit) return strip and lpegmatch(stripper,str) or str end if id == glue_code then - d = getfield(d,"spec") + d = d.spec end - if not d or not getid(d) == gluespec_code then + if not d or not d.id == gluespec_code then local str = formatters[fmt](0,unit) return strip and lpegmatch(stripper,str) or str end - local width = getfield(d,"width") - local plus = getfield(d,"stretch_order") - local minus = getfield(d,"shrink_order") - local stretch = getfield(d,"stretch") - local shrink = getfield(d,"shrink") + local width = d.width + local plus = d.stretch_order + local minus = d.shrink_order + local stretch = d.stretch + local shrink = d.shrink if plus ~= 0 then plus = " plus " .. stretch/65536 .. fillcodes[plus] elseif stretch ~= 0 then @@ -401,39 +379,11 @@ local function nodetodimen(d,unit,fmt,strip) else minus = "" end - local str = formatters[fmt](getfield(d,"width")*dimenfactors[unit],unit) + local str = formatters[fmt](d.width*dimenfactors[unit],unit) return (strip and lpegmatch(stripper,str) or str) .. plus .. minus end -local function numbertodimen(d,unit,fmt,strip) - if not d then - local str = formatters[fmt](0,unit) - return strip and lpegmatch(stripper,str) or str - end - local t = type(d) - if t == 'string' then - return d - elseif t == "number" then - if unit == true then - unit = "pt" - fmt = "%0.5f%s" - else - unit = unit or 'pt' - if not fmt then - fmt = "%s%s" - elseif fmt == true then - fmt = "%0.5f%s" - end - end - local str = formatters[fmt](d*dimenfactors[unit],unit) - return strip and lpegmatch(stripper,str) or str - else - return nodetodimen(d,unit,fmt,strip) -- real node - end -end - number.todimen = numbertodimen -nodes .todimen = nodetodimen function number.topoints (n,fmt) return numbertodimen(n,"pt",fmt) end function number.toinches (n,fmt) return numbertodimen(n,"in",fmt) end @@ -448,19 +398,6 @@ function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end -function nodes.topoints (n,fmt) return nodetodimen(n,"pt",fmt) end -function nodes.toinches (n,fmt) return nodetodimen(n,"in",fmt) end -function nodes.tocentimeters (n,fmt) return nodetodimen(n,"cm",fmt) end -function nodes.tomillimeters (n,fmt) return nodetodimen(n,"mm",fmt) end -function nodes.toscaledpoints(n,fmt) return nodetodimen(n,"sp",fmt) end -function nodes.toscaledpoints(n) return n .. "sp" end -function nodes.tobasepoints (n,fmt) return nodetodimen(n,"bp",fmt) end -function nodes.topicas (n,fmt) return nodetodimen(n "pc",fmt) end -function nodes.todidots (n,fmt) return nodetodimen(n,"dd",fmt) end -function nodes.tociceros (n,fmt) return nodetodimen(n,"cc",fmt) end -function nodes.tonewdidots (n,fmt) return nodetodimen(n,"nd",fmt) end -function nodes.tonewciceros (n,fmt) return nodetodimen(n,"nc",fmt) end - -- stop redefinition local points = function(n) @@ -506,13 +443,8 @@ number.basepoints = basepoints number.pts = pts number.nopts = nopts -nodes.points = function(n) return numbertodimen(n,"pt",true,true) end -nodes.basepoints = function(n) return numbertodimen(n,"bp",true,true) end -nodes.pts = function(n) return numbertodimen(n,"pt",true) end -nodes.nopts = function(n) return format("%.5f",n*ptfactor) end - -local colors = { } -tracers.colors = colors +local colors = { } +tracers.colors = colors local unsetvalue = attributes.unsetvalue @@ -522,34 +454,36 @@ local m_color = attributes.list[a_color] or { } function colors.set(n,c,s) local mc = m_color[c] - local nn = tonut(n) - if mc then - local mm = s or texgetattribute(a_colormodel) - setattr(nn,a_colormodel,mm <= 0 and mm or 1) - setattr(nn,a_color,mc) + if not mc then + n[a_color] = unsetvalue else - setattr(nn,a_color,unsetvalue) + if not n[a_colormodel] then + n[a_colormodel] = s or 1 + end + n[a_color] = mc end return n end function colors.setlist(n,c,s) - local nn = tonut(n) - local mc = m_color[c] or unsetvalue - local mm = s or texgetattribute(a_colormodel) - if mm <= 0 then - mm = 1 - end - while nn do - setattr(nn,a_colormodel,mm) - setattr(nn,a_color,mc) - nn = getnext(nn) + local f = n + while n do + local mc = m_color[c] + if not mc then + n[a_color] = unsetvalue + else + if not n[a_colormodel] then + n[a_colormodel] = s or 1 + end + n[a_color] = mc + end + n = n.next end - return n + return f end function colors.reset(n) - setattr(tonut(n),a_color,unsetvalue) + n[a_color] = unsetvalue return n end @@ -562,22 +496,31 @@ local a_transparency = attributes.private('transparency') local m_transparency = attributes.list[a_transparency] or { } function transparencies.set(n,t) - setattr(tonut(n),a_transparency,m_transparency[t] or unsetvalue) + local mt = m_transparency[t] + if not mt then + n[a_transparency] = unsetvalue + else + n[a_transparency] = mt + end return n end function transparencies.setlist(n,c,s) - local nn = tonut(n) - local mt = m_transparency[c] or unsetvalue - while nn do - setattr(nn,a_transparency,mt) - nn = getnext(nn) + local f = n + while n do + local mt = m_transparency[c] + if not mt then + n[a_transparency] = unsetvalue + else + n[a_transparency] = mt + end + n = n.next end - return n + return f end function transparencies.reset(n) - setattr(n,a_transparency,unsetvalue) + n[a_transparency] = unsetvalue return n end @@ -594,76 +537,52 @@ end -- although tracers are used seldom local function setproperties(n,c,s) - local nn = tonut(n) local mm = texgetattribute(a_colormodel) - setattr(nn,a_colormodel,mm > 0 and mm or 1) - setattr(nn,a_color,m_color[c]) - setattr(nn,a_transparency,m_transparency[c]) + n[a_colormodel] = mm > 0 and mm or 1 + n[a_color] = m_color[c] + n[a_transparency] = m_transparency[c] return n end tracers.setproperties = setproperties -function tracers.setlist(n,c,s) - local nn = tonut(n) +function tracers.setlistv(n,c,s) + local f = n local mc = m_color[c] local mt = m_transparency[c] local mm = texgetattribute(a_colormodel) if mm <= 0 then mm = 1 end - while nn do - setattr(nn,a_colormodel,mm) - setattr(nn,a_color,mc) - setattr(nn,a_transparency,mt) - nn = getnext(nn) + while n do + n[a_colormodel] = mm + n[a_color] = mc + n[a_transparency] = mt + n = n.next end - return n + return f end function tracers.resetproperties(n) - local nn = tonut(n) - setattr(nn,a_color,unsetvalue) - setattr(nn,a_transparency,unsetvalue) + n[a_color] = unsetvalue + n[a_transparency] = unsetvalue return n end --- this one returns a nut +function tracers.rule(w,h,d,c,s) -- so some day we can consider using literals (speedup) + return setproperties(new_rule(w,h,d),c,s) +end + +-- only nodes local nodestracerpool = { } -local nutstracerpool = { } tracers.pool = { nodes = nodestracerpool, - nuts = nutstracerpool, } -table.setmetatableindex(nodestracerpool,function(t,k,v) - local f = nutstracerpool[k] - local v = function(...) - return tonode(f(...)) - end - t[k] = v - return v -end) - -function nutstracerpool.rule(w,h,d,c,s) -- so some day we can consider using literals (speedup) +function nodestracerpool.rule(w,h,d,c,s) -- so some day we can consider using literals (speedup) return setproperties(new_rule(w,h,d),c,s) end tracers.rule = nodestracerpool.rule -- for a while - --- local function show(head,n,message) --- print("START",message or "") --- local i = 0 --- for current in traverse(head) do --- local prev = getprev(current) --- local next = getnext(current) --- i = i + 1 --- print(i, prev and nodecodes[getid(prev)],nodecodes[getid(current)],next and nodecodes[getid(next)]) --- if i == n then --- break --- end --- end --- print("STOP", message or "") --- end |