summaryrefslogtreecommitdiff
path: root/tex/context/base/node-tra.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/node-tra.lua')
-rw-r--r--tex/context/base/node-tra.lua355
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