summaryrefslogtreecommitdiff
path: root/tex/context/base/node-fin.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/node-fin.lua')
-rw-r--r--tex/context/base/node-fin.lua302
1 files changed, 125 insertions, 177 deletions
diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua
index 8476b47a6..63a5ef83e 100644
--- a/tex/context/base/node-fin.lua
+++ b/tex/context/base/node-fin.lua
@@ -8,54 +8,36 @@ if not modules then modules = { } end modules ['node-fin'] = {
-- this module is being reconstructed
-- local functions, only slightly slower
---
--- leaders are also triggers
local next, type, format = next, type, string.format
local attributes, nodes, node = attributes, nodes, node
-local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
-local getfield = nuts.getfield
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getid = nuts.getid
-local getlist = nuts.getlist
-local getleader = nuts.getleader
-local getattr = nuts.getattr
-
-local setfield = nuts.setfield
-local setattr = nuts.setattr
-
-local copy_node = nuts.copy
-local insert_node_before = nuts.insert_before
-local insert_node_after = nuts.insert_after
+local copy_node = node.copy
+local find_tail = node.slide
-local nodecodes = nodes.nodecodes
-local whatcodes = nodes.whatcodes
+local nodecodes = nodes.nodecodes
+local whatcodes = nodes.whatcodes
-local glyph_code = nodecodes.glyph
-local disc_code = nodecodes.disc
-local glue_code = nodecodes.glue
-local rule_code = nodecodes.rule
-local whatsit_code = nodecodes.whatsit
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
+local glyph_code = nodecodes.glyph
+local disc_code = nodecodes.disc
+local glue_code = nodecodes.glue
+local rule_code = nodecodes.rule
+local whatsit_code = nodecodes.whatsit
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
-local pdfliteral_code = whatcodes.pdfliteral
+local pdfliteral_code = whatcodes.pdfliteral
-local states = attributes.states
-local numbers = attributes.numbers
-local a_trigger = attributes.private('trigger')
-local triggering = false
+local states = attributes.states
+local numbers = attributes.numbers
+local a_trigger = attributes.private('trigger')
+local triggering = false
-local starttiming = statistics.starttiming
-local stoptiming = statistics.stoptiming
-local loadstripped = utilities.lua.loadstripped
-local unsetvalue = attributes.unsetvalue
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
+local loadstripped = utilities.lua.loadstripped
+local unsetvalue = attributes.unsetvalue
-- these two will be like trackers
@@ -120,14 +102,11 @@ function nodes.installattributehandler(plugin)
return loadstripped(template)()
end
--- for the moment:
-
-local function copied(n)
- return copy_node(tonut(n))
-end
-
-- the injectors
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+
local nsdata, nsnone, nslistwise, nsforced, nsselector, nstrigger
local current, current_selector, done = 0, 0, false -- nb, stack has a local current !
local nsbegin, nsend
@@ -153,25 +132,23 @@ end
function states.finalize(namespace,attribute,head) -- is this one ok?
if current > 0 and nsnone then
- head = tonut(head)
- local id = getid(head)
+ local id = head.id
if id == hlist_code or id == vlist_code then
- local list = getlist(head)
+ local list = head.list
if list then
- list = insert_node_before(list,list,copied(nsnone)) -- two return values
- setfield(head,"list",list)
+ head.list = insert_node_before(list,list,copy_node(nsnone))
end
else
- head = insert_node_before(head,head,copied(nsnone))
+ head = insert_node_before(head,head,copy_node(nsnone))
end
- return tonode(head), true, true
+ return head, true, true
end
return head, false, false
end
-- disc nodes can be ignored
-- we need to deal with literals too (reset as well as oval)
--- if id == glyph_code or (id == whatsit_code and getsubtype(stack) == pdfliteral_code) or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then
+-- if id == glyph_code or (id == whatsit_code and stack.subtype == pdfliteral_code) or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then
local function process(namespace,attribute,head,inheritance,default) -- one attribute
local stack = head
@@ -179,57 +156,53 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr
local check = false
local leader = nil
while stack do
- local id = getid(stack)
+ local id = stack.id
if id == glyph_code then
check = true
elseif id == glue_code then
- leader = getleader(stack)
+ leader = stack.leader
if leader then
check = true
end
elseif id == hlist_code or id == vlist_code then
- local content = getlist(stack)
+ local content = stack.list
if content then
-- begin nested --
- if nstrigger and getattr(stack,nstrigger) then
- local outer = getattr(stack,attribute)
+ local ok
+ if nstrigger and stack[nstrigger] then
+ local outer = stack[attribute]
if outer ~= inheritance then
- local list, ok = process(namespace,attribute,content,inheritance,outer)
- setfield(stack,"list",list)
- done = done or ok
+ stack.list, ok = process(namespace,attribute,content,inheritance,outer)
else
- local list, ok = process(namespace,attribute,content,inheritance,default)
- setfield(stack,"list",list)
- done = done or ok
+ stack.list, ok = process(namespace,attribute,content,inheritance,default)
end
else
- local list, ok = process(namespace,attribute,content,inheritance,default)
- setfield(stack,"list",list)
- done = done or ok
+ stack.list, ok = process(namespace,attribute,content,inheritance,default)
end
-- end nested --
+ done = done or ok
end
elseif id == rule_code then
- check = getfield(stack,"width") ~= 0
+ check = stack.width ~= 0
end
-- much faster this way than using a check() and nested() function
if check then
- local c = getattr(stack,attribute)
+ local c = stack[attribute]
if c then
if default and c == inheritance then
if current ~= default then
- head = insert_node_before(head,stack,copied(nsdata[default]))
+ head = insert_node_before(head,stack,copy_node(nsdata[default]))
current = default
done = true
end
elseif current ~= c then
- head = insert_node_before(head,stack,copied(nsdata[c]))
+ head = insert_node_before(head,stack,copy_node(nsdata[c]))
current = c
done = true
end
if leader then
local savedcurrent = current
- local ci = getid(leader)
+ local ci = leader.id
if ci == hlist_code or ci == vlist_code then
-- else we reset inside a box unneeded, okay, the downside is
-- that we trigger color in each repeated box, so there is room
@@ -237,48 +210,41 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr
current = 0
end
-- begin nested --
- if nstrigger and getattr(stack,nstrigger) then
- local outer = getattr(stack,attribute)
+ local ok = false
+ if nstrigger and stack[nstrigger] then
+ local outer = stack[attribute]
if outer ~= inheritance then
- local list, ok = process(namespace,attribute,leader,inheritance,outer)
- setfield(stack,"leader",list)
- done = done or ok
+ stack.leader, ok = process(namespace,attribute,leader,inheritance,outer)
else
- local list, ok = process(namespace,attribute,leader,inheritance,default)
- setfield(stack,"leader",list)
- done = done or ok
+ stack.leader, ok = process(namespace,attribute,leader,inheritance,default)
end
else
- local list, ok = process(namespace,attribute,leader,inheritance,default)
- setfield(stack,"leader",list)
- done = done or ok
+ stack.leader, ok = process(namespace,attribute,leader,inheritance,default)
end
-- end nested --
+ done = done or ok
current = savedcurrent
leader = false
end
elseif default and inheritance then
if current ~= default then
- head = insert_node_before(head,stack,copied(nsdata[default]))
+ head = insert_node_before(head,stack,copy_node(nsdata[default]))
current = default
done = true
end
elseif current > 0 then
- head = insert_node_before(head,stack,copied(nsnone))
+ head = insert_node_before(head,stack,copy_node(nsnone))
current = 0
done = true
end
check = false
end
- stack = getnext(stack)
+ stack = stack.next
end
return head, done
end
-states.process = function(namespace,attribute,head,default)
- local head, done = process(namespace,attribute,tonut(head),default)
- return tonode(head), done
-end
+states.process = process
-- we can force a selector, e.g. document wide color spaces, saves a little
-- watch out, we need to check both the selector state (like colorspace) and
@@ -292,103 +258,93 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at
local check = false
local leader = nil
while stack do
- local id = getid(stack)
+ local id = stack.id
if id == glyph_code then
check = true
elseif id == glue_code then
- leader = getleader(stack)
+ leader = stack.leader
if leader then
check = true
end
elseif id == hlist_code or id == vlist_code then
- local content = getlist(stack)
+ local content = stack.list
if content then
+ local ok = false
-- begin nested
- if nstrigger and getattr(stack,nstrigger) then
- local outer = getattr(stack,attribute)
+ if nstrigger and stack[nstrigger] then
+ local outer = stack[attribute]
if outer ~= inheritance then
- local list, ok = selective(namespace,attribute,content,inheritance,outer)
- setfield(stack,"list",list)
- done = done or ok
+ stack.list, ok = selective(namespace,attribute,content,inheritance,outer)
else
- local list, ok = selective(namespace,attribute,content,inheritance,default)
- setfield(stack,"list",list)
- done = done or ok
+ stack.list, ok = selective(namespace,attribute,content,inheritance,default)
end
else
- local list, ok = selective(namespace,attribute,content,inheritance,default)
- setfield(stack,"list",list)
- done = done or ok
+ stack.list, ok = selective(namespace,attribute,content,inheritance,default)
end
-- end nested
+ done = done or ok
end
elseif id == rule_code then
- check = getfield(stack,"width") ~= 0
+ check = stack.width ~= 0
end
if check then
- local c = getattr(stack,attribute)
+ local c = stack[attribute]
if c then
if default and c == inheritance then
if current ~= default then
local data = nsdata[default]
- head = insert_node_before(head,stack,copied(data[nsforced or getattr(stack,nsselector) or nsselector]))
+ head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
current = default
done = true
end
else
- local s = getattr(stack,nsselector)
+ local s = stack[nsselector]
if current ~= c or current_selector ~= s then
local data = nsdata[c]
- head = insert_node_before(head,stack,copied(data[nsforced or getattr(stack,nsselector) or nsselector]))
+ head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
current = c
current_selector = s
done = true
end
end
if leader then
+ local ok = false
-- begin nested
- if nstrigger and getattr(stack,nstrigger) then
- local outer = getatribute(stack,attribute)
+ if nstrigger and stack[nstrigger] then
+ local outer = stack[attribute]
if outer ~= inheritance then
- local list, ok = selective(namespace,attribute,leader,inheritance,outer)
- setfield(stack,"leader",list)
- done = done or ok
+ stack.leader, ok = selective(namespace,attribute,leader,inheritance,outer)
else
- local list, ok = selective(namespace,attribute,leader,inheritance,default)
- setfield(stack,"leader",list)
- done = done or ok
+ stack.leader, ok = selective(namespace,attribute,leader,inheritance,default)
end
else
- local list, ok = selective(namespace,attribute,leader,inheritance,default)
- setfield(stack,"leader",list)
- done = done or ok
+ stack.leader, ok = selective(namespace,attribute,leader,inheritance,default)
end
-- end nested
- leader = false
+ done = done or ok
+ leader = false
end
elseif default and inheritance then
if current ~= default then
local data = nsdata[default]
- head = insert_node_before(head,stack,copied(data[nsforced or getattr(stack,nsselector) or nsselector]))
+ head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
current = default
done = true
end
elseif current > 0 then
- head = insert_node_before(head,stack,copied(nsnone))
+ head = insert_node_before(head,stack,copy_node(nsnone))
current, current_selector, done = 0, 0, true
end
check = false
end
- stack = getnext(stack)
+
+ stack = stack.next
end
return head, done
end
-states.selective = function(namespace,attribute,head,default)
- local head, done = selective(namespace,attribute,tonut(head),default)
- return tonode(head), done
-end
+states.selective = selective
-- Ideally the next one should be merged with the previous but keeping it separate is
-- safer. We deal with two situations: efficient boxwise (layoutareas) and mixed layers
@@ -407,80 +363,76 @@ local function stacked(namespace,attribute,head,default) -- no triggering, no in
local check = false
local leader = false
while stack do
- local id = getid(stack)
+ local id = stack.id
if id == glyph_code then
check = true
elseif id == glue_code then
- leader = getleader(stack)
+ leader = stack.leader
if leader then
check = true
end
elseif id == hlist_code or id == vlist_code then
- local content = getlist(stack)
+ local content = stack.list
if content then
-- the problem is that broken lines gets the attribute which can be a later one
if nslistwise then
- local a = getattr(stack,attribute)
+ local a = stack[attribute]
if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below
local p = current
- current = a
- head = insert_node_before(head,stack,copied(nsdata[a]))
- local list = stacked(namespace,attribute,content,current) -- two return values
- setfield(stack,"list",list)
- done = true
- head, stack = insert_node_after(head,stack,copied(nsnone))
+ current, done = a, true
+ head = insert_node_before(head,stack,copy_node(nsdata[a]))
+ stack.list = stacked(namespace,attribute,content,current)
+ head, stack = insert_node_after(head,stack,copy_node(nsnone))
current = p
else
- local list, ok = stacked(namespace,attribute,content,current)
- setfield(stack,"list",list) -- only if ok
+ local ok = false
+ stack.list, ok = stacked(namespace,attribute,content,current)
done = done or ok
end
else
- local list, ok = stacked(namespace,attribute,content,current)
- setfield(stack,"list",list) -- only if ok
+ local ok = false
+ stack.list, ok = stacked(namespace,attribute,content,current)
done = done or ok
end
end
elseif id == rule_code then
- check = getfield(stack,"width") ~= 0
+ check = stack.width ~= 0
end
if check then
- local a = getattr(stack,attribute)
+ local a = stack[attribute]
if a then
if current ~= a then
- head = insert_node_before(head,stack,copied(nsdata[a]))
+ head = insert_node_before(head,stack,copy_node(nsdata[a]))
depth = depth + 1
current, done = a, true
end
if leader then
- local list, ok = stacked(namespace,attribute,content,current)
- setfield(stack,"leader",list) -- only if ok
+ local ok = false
+ stack.leader, ok = stacked(namespace,attribute,content,current)
done = done or ok
leader = false
end
elseif default > 0 then
--
elseif current > 0 then
- head = insert_node_before(head,stack,copied(nsnone))
+ head = insert_node_before(head,stack,copy_node(nsnone))
depth = depth - 1
current, done = 0, true
end
check = false
end
- stack = getnext(stack)
+
+ stack = stack.next
end
while depth > 0 do
- head = insert_node_after(head,stack,copied(nsnone))
+ head = insert_node_after(head,stack,copy_node(nsnone))
depth = depth - 1
end
return head, done
end
-states.stacked = function(namespace,attribute,head,default)
- local head, done = stacked(namespace,attribute,tonut(head),default)
- return tonode(head), done
-end
+states.stacked = stacked
-- experimental
@@ -494,53 +446,52 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in
local check = false
local leader = false
while current do
- local id = getid(current)
+ local id = current.id
if id == glyph_code then
check = true
elseif id == glue_code then
- leader = getleader(current)
+ leader = current.leader
if leader then
check = true
end
elseif id == hlist_code or id == vlist_code then
- local content = getlist(current)
+ local content = current.list
if not content then
-- skip
elseif nslistwise then
- local a = getattr(current,attribute)
+ local a = current[attribute]
if a and attrib ~= a and nslistwise[a] then -- viewerlayer
- head = insert_node_before(head,current,copied(nsdata[a]))
- local list = stacker(namespace,attribute,content,a)
- setfield(current,"list",list)
done = true
- head, current = insert_node_after(head,current,copied(nsnone))
+ head = insert_node_before(head,current,copy_node(nsdata[a]))
+ current.list = stacker(namespace,attribute,content,a)
+ head, current = insert_node_after(head,current,copy_node(nsnone))
else
- local list, ok = stacker(namespace,attribute,content,attrib)
- setfield(current,"list",list)
+ local ok = false
+ current.list, ok = stacker(namespace,attribute,content,attrib)
done = done or ok
end
else
- local list, ok = stacker(namespace,attribute,content,default)
- setfield(current,"list",list)
+ local ok = false
+ current.list, ok = stacker(namespace,attribute,content,default)
done = done or ok
end
elseif id == rule_code then
- check = getfield(current,"width") ~= 0
+ check = current.width ~= 0
end
if check then
- local a = getattr(current,attribute) or unsetvalue
+ local a = current[attribute] or unsetvalue
if a ~= attrib then
local n = nsstep(a)
if n then
-- !!!! TEST CODE !!!!
- -- head = insert_node_before(head,current,copied(nsdata[tonumber(n)])) -- a
- head = insert_node_before(head,current,tonut(n)) -- a
+ -- head = insert_node_before(head,current,copy_node(nsdata[tonumber(n)])) -- a
+ head = insert_node_before(head,current,n) -- a
end
attrib, done, okay = a, true, true
if leader then
-- tricky as a leader has to be a list so we cannot inject before
- local list, ok = stacker(namespace,attribute,leader,attrib)
+ local _, ok = stacker(namespace,attribute,leader,attrib)
done = done or ok
leader = false
end
@@ -549,23 +500,20 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in
end
previous = current
- current = getnext(current)
+ current = current.next
end
if okay then
local n = nsend()
if n then
-- !!!! TEST CODE !!!!
- -- head = insert_node_after(head,previous,copied(nsdata[tostring(n)]))
- head = insert_node_after(head,previous,tonut(n))
+ -- head = insert_node_after(head,previous,copy_node(nsdata[tostring(n)]))
+ head = insert_node_after(head,previous,n)
end
end
return head, done
end
-states.stacker = function(namespace,attribute,head,default)
- local head, done = stacker(namespace,attribute,tonut(head),default)
- return tonode(head), done
-end
+states.stacker = stacker
-- -- --