summaryrefslogtreecommitdiff
path: root/tex/context/base/node-tra.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2014-01-07 14:00:00 +0100
committerHans Hagen <pragma@wxs.nl>2014-01-07 14:00:00 +0100
commit539201b19e95e9e3c2279e12485866e2f0919262 (patch)
tree65f83e1f68182112f519cc84104d4f4db7653c3d /tex/context/base/node-tra.lua
parenta50b4f9b35ed19c921b861bcc9ef5f6202c6cef0 (diff)
downloadcontext-539201b19e95e9e3c2279e12485866e2f0919262.tar.gz
beta 2014.01.07 14:00
Diffstat (limited to 'tex/context/base/node-tra.lua')
-rw-r--r--tex/context/base/node-tra.lua341
1 files changed, 204 insertions, 137 deletions
diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua
index 9617f7476..89c3e52f9 100644
--- a/tex/context/base/node-tra.lua
+++ b/tex/context/base/node-tra.lua
@@ -34,9 +34,30 @@ nodes.handlers = handlers
local injections = nodes.injections or { }
nodes.injections = injections
-local traverse_nodes = node.traverse
-local traverse_by_id = node.traverse_id
-local count_nodes = nodes.count
+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 nodecodes = nodes.nodecodes
local whatcodes = nodes.whatcodes
@@ -56,9 +77,6 @@ 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
@@ -68,15 +86,16 @@ function nodes.showlist(head, message)
if message then
report_nodes(message)
end
- for n in traverse_nodes(head) do
- report_nodes(tostring(n))
+ for n in traverse_nodes(tonut(head)) do
+ report_nodes(d_tostring(n))
end
end
function nodes.handlers.checkglyphs(head,message)
+ local h = tonut(head)
local t = { }
- for g in traverse_by_id(glyph_code,head) do
- t[#t+1] = formatters["%U:%s"](g.char,g.subtype)
+ for g in traverse_by_id(glyph_code,h) do
+ t[#t+1] = formatters["%U:%s"](getchar(g),getsubtype(g))
end
if #t > 0 then
if message and message ~= "" then
@@ -90,12 +109,12 @@ end
function nodes.handlers.checkforleaks(sparse)
local l = { }
- local q = node.usedlist()
- for p in traverse(q) do
- local s = table.serialize(nodes.astable(p,sparse),nodecodes[p.id])
+ local q = used_nodes()
+ for p in traverse_nodes(q) do
+ local s = table.serialize(nodes.astable(p,sparse),nodecodes[getid(p)])
l[s] = (l[s] or 0) + 1
end
- node.flush_list(q)
+ flush_list(q)
for k, v in next, l do
report_nodes("%s * %s",v,k)
end
@@ -105,39 +124,40 @@ 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 = start.id
+ local id = getid(start)
if id == glyph_code then
- local c = start.char
+ local c = getchar(start)
if compact then
- if start.components then
- t[#t+1] = tosequence(start.components,nil,compact)
+ local components = getfield(start,"components")
+ if components then
+ t[#t+1] = tosequence(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
- if compact then
- t[#t+1] = "[]"
- else
- t[#t+1] = nodecodes[id]
- end
+ t[#t+1] = nodecodes[id]
end
if start == stop then
break
else
- start = start.next
+ start = getnext(start)
end
end
if compact then
@@ -153,21 +173,23 @@ end
nodes.tosequence = tosequence
function nodes.report(t,done)
- report_nodes("output %a, %changed %a, %s nodes",status.output_active,done,count_nodes(t))
+ report_nodes("output %a, %changed %a, %s nodes",status.output_active,done,count_nodes(tonut(t)))
end
function nodes.packlist(head)
local t = { }
- for n in traverse(head) do
- t[#t+1] = tostring(n)
+ for n in traverse_nodes(tonut(head)) do
+ t[#t+1] = d_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 = n.id
+ local id = getid(n)
if not last_id then
last_id, last_n = id, 1
elseif last_id == id then
@@ -195,6 +217,8 @@ 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
@@ -217,7 +241,7 @@ end
-- if n == head then
-- break
-- end
--- n = n.prev
+-- n = getprev(n)
-- end
-- if not last_id then
-- t[#t+1] = "no nodes"
@@ -230,51 +254,56 @@ 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 = h.id
+ local id = getid(h)
if id == hlist_code or id == vlist_code then
- showsimplelist(h.list,depth,n+1)
+ showsimplelist(getlist(h),depth,n+1)
end
end
- h = h.next
+ h = getnext(h)
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 = h.id
+ local id = getid(h)
if id == glyph_code then -- always true
- local c = h.char
+ local c = getchar(h)
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 = h.pre
- local pos = h.post
- local rep = h.replace
+ local pre = getfield(h,"pre")
+ local pos = getfield(h,"post")
+ local rep = getfield(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 and h.spec and h.spec.width > 0 then
- w[#w+1] = " "
+ 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] = "[]"
end
else
w[#w+1] = "[-]"
@@ -282,24 +311,28 @@ local function listtoutf(h,joiner,textonly,last)
if h == last then
break
else
- h = h.next
+ h = getnext(h)
end
end
return concat(w)
end
-nodes.listtoutf = listtoutf
+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
local what = { [0] = "unknown", "line", "box", "indent", "row", "cell" }
local function showboxes(n,symbol,depth)
- depth, symbol = depth or 0, symbol or "."
- for n in traverse_nodes(n) do
- local id = n.id
+ depth = depth or 0
+ symbol = symbol or "."
+ for n in traverse_nodes(tonut(n)) do
+ local id = getid(n)
if id == hlist_code or id == vlist_code then
- local s = n.subtype
+ local s = getsubtype(n)
report_nodes(rep(symbol,depth) .. what[s] or s)
- showboxes(n.list,symbol,depth+1)
+ showboxes(getlist(n),symbol,depth+1)
end
end
end
@@ -322,15 +355,8 @@ local stripper = lpeg.patterns.stripzeros
local dimenfactors = number.dimenfactors
-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
+local function nodetodimen(d,unit,fmt,strip)
+ d = tonut(d) -- tricky: direct nuts are an issue
if unit == true then
unit = "pt"
fmt = "%0.5f%s"
@@ -342,27 +368,23 @@ local function numbertodimen(d,unit,fmt,strip)
fmt = "%0.5f%s"
end
end
- 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
+ local id = getid(d)
if id == kern_code then
- local str = formatters[fmt](d.width*dimenfactors[unit],unit)
+ local str = formatters[fmt](getfield(d,"width")*dimenfactors[unit],unit)
return strip and lpegmatch(stripper,str) or str
end
if id == glue_code then
- d = d.spec
+ d = getfield(d,"spec")
end
- if not d or not d.id == gluespec_code then
+ if not d or not getid(d) == gluespec_code then
local str = formatters[fmt](0,unit)
return strip and lpegmatch(stripper,str) or str
end
- local width = d.width
- local plus = d.stretch_order
- local minus = d.shrink_order
- local stretch = d.stretch
- local shrink = d.shrink
+ 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")
if plus ~= 0 then
plus = " plus " .. stretch/65536 .. fillcodes[plus]
elseif stretch ~= 0 then
@@ -379,11 +401,39 @@ local function numbertodimen(d,unit,fmt,strip)
else
minus = ""
end
- local str = formatters[fmt](d.width*dimenfactors[unit],unit)
+ local str = formatters[fmt](getfield(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
@@ -398,6 +448,19 @@ 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)
@@ -443,8 +506,13 @@ number.basepoints = basepoints
number.pts = pts
number.nopts = nopts
-local colors = { }
-tracers.colors = colors
+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 unsetvalue = attributes.unsetvalue
@@ -454,36 +522,34 @@ local m_color = attributes.list[a_color] or { }
function colors.set(n,c,s)
local mc = m_color[c]
- if not mc then
- n[a_color] = unsetvalue
+ 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)
else
- if not n[a_colormodel] then
- n[a_colormodel] = s or 1
- end
- n[a_color] = mc
+ setattr(nn,a_color,unsetvalue)
end
return n
end
function colors.setlist(n,c,s)
- 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
+ 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)
end
- return f
+ return n
end
function colors.reset(n)
- n[a_color] = unsetvalue
+ setattr(tonut(n),a_color,unsetvalue)
return n
end
@@ -496,31 +562,22 @@ local a_transparency = attributes.private('transparency')
local m_transparency = attributes.list[a_transparency] or { }
function transparencies.set(n,t)
- local mt = m_transparency[t]
- if not mt then
- n[a_transparency] = unsetvalue
- else
- n[a_transparency] = mt
- end
+ setattr(tonut(n),a_transparency,m_transparency[t] or unsetvalue)
return n
end
function transparencies.setlist(n,c,s)
- 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
+ local nn = tonut(n)
+ local mt = m_transparency[c] or unsetvalue
+ while nn do
+ setattr(nn,a_transparency,mt)
+ nn = getnext(nn)
end
- return f
+ return n
end
function transparencies.reset(n)
- n[a_transparency] = unsetvalue
+ setattr(n,a_transparency,unsetvalue)
return n
end
@@ -537,52 +594,62 @@ end
-- although tracers are used seldom
local function setproperties(n,c,s)
+ local nn = tonut(n)
local mm = texgetattribute(a_colormodel)
- n[a_colormodel] = mm > 0 and mm or 1
- n[a_color] = m_color[c]
- n[a_transparency] = m_transparency[c]
+ setattr(nn,a_colormodel,mm > 0 and mm or 1)
+ setattr(nn,a_color,m_color[c])
+ setattr(nn,a_transparency,m_transparency[c])
return n
end
tracers.setproperties = setproperties
-function tracers.setlistv(n,c,s)
- local f = n
+function tracers.setlist(n,c,s)
+ local nn = tonut(n)
local mc = m_color[c]
local mt = m_transparency[c]
local mm = texgetattribute(a_colormodel)
if mm <= 0 then
mm = 1
end
- while n do
- n[a_colormodel] = mm
- n[a_color] = mc
- n[a_transparency] = mt
- n = n.next
+ while nn do
+ setattr(nn,a_colormodel,mm)
+ setattr(nn,a_color,mc)
+ setattr(nn,a_transparency,mt)
+ nn = getnext(nn)
end
- return f
+ return n
end
function tracers.resetproperties(n)
- n[a_color] = unsetvalue
- n[a_transparency] = unsetvalue
+ local nn = tonut(n)
+ setattr(nn,a_color,unsetvalue)
+ setattr(nn,a_transparency,unsetvalue)
return n
end
-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
+-- this one returns a nut
local nodestracerpool = { }
+local nutstracerpool = { }
tracers.pool = {
nodes = nodestracerpool,
+ nuts = nutstracerpool,
}
-function nodestracerpool.rule(w,h,d,c,s) -- so some day we can consider using literals (speedup)
+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)
return setproperties(new_rule(w,h,d),c,s)
end
tracers.rule = nodestracerpool.rule -- for a while
+