summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/node-fin.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mkiv/node-fin.lua472
1 files changed, 209 insertions, 263 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua b/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua
index dc681d16556..975eb0becc0 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua
@@ -16,15 +16,16 @@ 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 getnext = nuts.getnext
+local getprev = nuts.getprev
local getid = nuts.getid
local getlist = nuts.getlist
local getleader = nuts.getleader
local getattr = nuts.getattr
local getwidth = nuts.getwidth
-local getwhd = nuts.getwhd
-local getorientation = nuts.getorientation
local setlist = nuts.setlist
local setleader = nuts.setleader
@@ -33,22 +34,10 @@ local copy_node = nuts.copy
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
-local nextnode = nuts.traversers.node
-
local nodecodes = nodes.nodecodes
+local whatcodes = nodes.whatcodes
local rulecodes = nodes.rulecodes
------ normalrule_code = rulecodes.normal
-local boxrule_code = rulecodes.box
-local imagerule_code = rulecodes.image
-local emptyrule_code = rulecodes.empty
------ userrule_code = rulecodes.user
------ overrule_code = rulecodes.over
------ underrule_code = rulecodes.under
------ fractionrule_code = rulecodes.fraction
------ radicalrule_code = rulecodes.radical
------ outlinerule_code = rulecodes.outline
-
local glyph_code = nodecodes.glyph
local disc_code = nodecodes.disc
local glue_code = nodecodes.glue
@@ -93,34 +82,37 @@ local finalizer = plugin.finalizer
local flusher = plugin.flusher
if not processor then
return function(head)
- return head
+ return head, false
end
elseif initializer or finalizer or resolver then
return function(head)
starttiming(attributes)
- local used, inheritance
+ local done, used, ok, inheritance = false, nil, false, nil
if resolver then
inheritance = resolver()
end
if initializer then
initializer(namespace,attribute,head)
end
- head = processor(namespace,attribute,head,inheritance)
- if finalizer then
- head, used = finalizer(namespace,attribute,head)
- if used and flusher then
- head = flusher(namespace,attribute,head,used)
+ head, ok = processor(namespace,attribute,head,inheritance)
+ if ok then
+ if finalizer then
+ head, ok, used = finalizer(namespace,attribute,head)
+ if used and flusher then
+ head = flusher(namespace,attribute,head,used)
+ end
end
+ done = true
end
stoptiming(attributes)
- return head
+ return head, done
end
else
return function(head)
starttiming(attributes)
- head = processor(namespace,attribute,head)
+ local head, done = processor(namespace,attribute,head)
stoptiming(attributes)
- return head
+ return head, done
end
end
nodes.plugindata = nil
@@ -134,7 +126,7 @@ end
-- the injectors
local nsdata, nsnone, nslistwise, nsforced, nsselector, nstrigger
-local current, current_selector = 0, 0 -- nb, stack has a local current !
+local current, current_selector, done = 0, 0, false -- nb, stack has a local current !
local nsbegin, nsend, nsreset
function states.initialize(namespace,attribute,head)
@@ -146,6 +138,7 @@ function states.initialize(namespace,attribute,head)
nstrigger = triggering and namespace.triggering and a_trigger
current = 0
current_selector = 0
+ done = false -- todo: done cleanup
nsstep = namespace.resolve_step
if nsstep then
nsreset = namespace.resolve_reset
@@ -158,6 +151,7 @@ end
function states.finalize(namespace,attribute,head) -- is this one ok?
if current > 0 and nsnone then
+ head = tonut(head)
local id = getid(head)
if id == hlist_code or id == vlist_code then
local content = getlist(head)
@@ -170,17 +164,20 @@ function states.finalize(namespace,attribute,head) -- is this one ok?
else
head = insert_node_before(head,head,copy_node(nsnone))
end
- return head, true
+ return tonode(head), true, true
end
- return head, false
+ return head, false, false
end
-- we need to deal with literals too (reset as well as oval)
local function process(attribute,head,inheritance,default) -- one attribute
+ local stack = head
+ local done = false
local check = false
local leader = nil
- for stack, id in nextnode, head do
+ while stack do
+ local id = getid(stack)
if id == glyph_code or id == disc_code then
check = true -- disc no longer needed as we flatten replace
elseif id == glue_code then
@@ -191,52 +188,39 @@ local function process(attribute,head,inheritance,default) -- one attribute
elseif id == hlist_code or id == vlist_code then
local content = getlist(stack)
if content then
- -- tricky checking
- local outer
- if getorientation(stack) then
- outer = getattr(stack,attribute)
- if outer then
- if default and outer == inheritance then
- if current ~= default then
- head = insert_node_before(head,stack,copy_node(nsdata[default]))
- current = default
- end
- elseif current ~= outer then
- head = insert_node_before(head,stack,copy_node(nsdata[c]))
- current = outer
- end
- elseif default and inheritance then
- if current ~= default then
- head = insert_node_before(head,stack,copy_node(nsdata[default]))
- current = default
- end
- elseif current > 0 then
- head = insert_node_before(head,stack,copy_node(nsnone))
- current = 0
- end
- end
-- begin nested --
- local list
if nstrigger and getattr(stack,nstrigger) then
- if not outer then
- outer = getattr(stack,attribute)
- end
+ local outer = getattr(stack,attribute)
if outer ~= inheritance then
- list = process(attribute,content,inheritance,outer)
+ local list, ok = process(attribute,content,inheritance,outer)
+ if content ~= list then
+ setlist(stack,list)
+ end
+ if ok then
+ done = true
+ end
else
- list = process(attribute,content,inheritance,default)
+ local list, ok = process(attribute,content,inheritance,default)
+ if content ~= list then
+ setlist(stack,list)
+ end
+ if ok then
+ done = true
+ end
end
else
- list = process(attribute,content,inheritance,default)
- end
- if content ~= list then
- setlist(stack,list)
+ local list, ok = process(attribute,content,inheritance,default)
+ if content ~= list then
+ setlist(stack,list)
+ end
+ if ok then
+ done = true
+ end
end
-- end nested --
end
elseif id == rule_code then
- local wd, ht, dp = getwhd(stack)
- check = wd ~= 0 or (ht+dp) ~= 0
+ check = getwidth(stack) ~= 0
end
-- much faster this way than using a check() and nested() function
if check then
@@ -246,10 +230,12 @@ local function process(attribute,head,inheritance,default) -- one attribute
if current ~= default then
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,copy_node(nsdata[c]))
current = c
+ done = true
end
if leader then
local savedcurrent = current
@@ -261,19 +247,33 @@ local function process(attribute,head,inheritance,default) -- one attribute
current = 0
end
-- begin nested --
- local list
if nstrigger and getattr(stack,nstrigger) then
local outer = getattr(stack,attribute)
if outer ~= inheritance then
- list = process(attribute,leader,inheritance,outer)
+ local list, ok = process(attribute,leader,inheritance,outer)
+ if leader ~= list then
+ setleader(stack,list)
+ end
+ if ok then
+ done = true
+ end
else
- list = process(attribute,leader,inheritance,default)
+ local list, ok = process(attribute,leader,inheritance,default)
+ if leader ~= list then
+ setleader(stack,list)
+ end
+ if ok then
+ done = true
+ end
end
else
- list = process(attribute,leader,inheritance,default)
- end
- if leader ~= list then
- setleader(stack,list)
+ local list, ok = process(attribute,leader,inheritance,default)
+ if leader ~= list then
+ setleader(stack,list)
+ end
+ if ok then
+ done = true
+ end
end
-- end nested --
current = savedcurrent
@@ -283,19 +283,23 @@ local function process(attribute,head,inheritance,default) -- one attribute
if current ~= default then
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,copy_node(nsnone))
current = 0
+ done = true
end
check = false
end
+ stack = getnext(stack)
end
- return head
+ return head, done
end
states.process = function(namespace,attribute,head,default)
- return process(attribute,head,default)
+ local head, done = process(attribute,tonut(head),default)
+ return tonode(head), done
end
-- we can force a selector, e.g. document wide color spaces, saves a little
@@ -305,9 +309,13 @@ end
-- each other with the same color but different color spaces e.g. \showcolor)
local function selective(attribute,head,inheritance,default) -- two attributes
+ -- local head = head
+ local stack = head
+ local done = false
local check = false
local leader = nil
- for stack, id, subtype in nextnode, head do
+ while stack do
+ local id = getid(stack)
if id == glyph_code or id == disc_code then
check = true -- disc no longer needed as we flatten replace
elseif id == glue_code then
@@ -318,66 +326,41 @@ local function selective(attribute,head,inheritance,default) -- two attributes
elseif id == hlist_code or id == vlist_code then
local content = getlist(stack)
if content then
- -- tricky checking
- local outer
- if getorientation(stack) then
- outer = getattr(stack,attribute)
- if outer then
- if default and outer == inheritance then
- if current ~= default then
- local data = nsdata[default]
- head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
- current = default
- end
- else
- local s = getattr(stack,nsselector)
- -- local s = nsforced or getattr(stack,nsselector)
- if current ~= outer or current_selector ~= s then
- local data = nsdata[outer]
- head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector]))
- current = outer
- current_selector = s
- end
- end
- elseif default and inheritance then
- if current ~= default then
- local data = nsdata[default]
- head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
- current = default
- end
- elseif current > 0 then
- head = insert_node_before(head,stack,copy_node(nsnone))
- current, current_selector = 0, 0
- end
- end
-- begin nested
- local list
if nstrigger and getattr(stack,nstrigger) then
- if not outer then
- outer = getattr(stack,attribute)
- end
+ local outer = getattr(stack,attribute)
if outer ~= inheritance then
- list = selective(attribute,content,inheritance,outer)
+ local list, ok = selective(attribute,content,inheritance,outer)
+ if content ~= list then
+ setlist(stack,list)
+ end
+ if ok then
+ done = true
+ end
else
- list = selective(attribute,content,inheritance,default)
+ local list, ok = selective(attribute,content,inheritance,default)
+ if content ~= list then
+ setlist(stack,list)
+ end
+ if ok then
+ done = true
+ end
end
else
- list = selective(attribute,content,inheritance,default)
- end
- if content ~= list then
- setlist(stack,list)
+ local list, ok = selective(attribute,content,inheritance,default)
+ if content ~= list then
+ setlist(stack,list)
+ end
+ if ok then
+ done = true
+ end
end
-- end nested
end
elseif id == rule_code then
- if subtype == boxrule_code or subtype == imagerule_code or subtype == emptyrule_code then
- -- so no redundant color stuff (only here, layers for instance should obey)
- check = false
- else
- local wd, ht, dp = getwhd(stack)
- check = wd ~= 0 or (ht+dp) ~= 0
- end
+ check = getwidth(stack) ~= 0
end
+
if check then
local c = getattr(stack,attribute)
if c then
@@ -386,6 +369,9 @@ local function selective(attribute,head,inheritance,default) -- two attributes
local data = nsdata[default]
head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
current = default
+ if ok then
+ done = true
+ end
end
else
local s = getattr(stack,nsselector)
@@ -393,25 +379,43 @@ local function selective(attribute,head,inheritance,default) -- two attributes
if current ~= c or current_selector ~= s then
local data = nsdata[c]
head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector]))
+ -- head = insert_node_before(head,stack,copy_node(data[s or nsselector]))
current = c
current_selector = s
+ if ok then
+ done = true
+ end
end
end
if leader then
-- begin nested
- local list
if nstrigger and getattr(stack,nstrigger) then
local outer = getattr(stack,attribute)
if outer ~= inheritance then
- list = selective(attribute,leader,inheritance,outer)
+ local list, ok = selective(attribute,leader,inheritance,outer)
+ if leader ~= list then
+ setleader(stack,list)
+ end
+ if ok then
+ done = true
+ end
else
- list = selective(attribute,leader,inheritance,default)
+ local list, ok = selective(attribute,leader,inheritance,default)
+ if leader ~= list then
+ setleader(stack,list)
+ end
+ if ok then
+ done = true
+ end
end
else
- list = selective(attribute,leader,inheritance,default)
- end
- if leader ~= list then
- setleader(stack,list)
+ local list, ok = selective(attribute,leader,inheritance,default)
+ if leader ~= list then
+ setleader(stack,list)
+ end
+ if ok then
+ done = true
+ end
end
-- end nested
leader = false
@@ -421,19 +425,22 @@ local function selective(attribute,head,inheritance,default) -- two attributes
local data = nsdata[default]
head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
current = default
+ done = true
end
elseif current > 0 then
head = insert_node_before(head,stack,copy_node(nsnone))
- current, current_selector = 0, 0
+ current, current_selector, done = 0, 0, true
end
check = false
end
+ stack = getnext(stack)
end
- return head
+ return head, done
end
states.selective = function(namespace,attribute,head,default)
- return selective(attribute,head,default)
+ local head = selective(attribute,tonut(head),default)
+ return tonode(head), true
end
-- Ideally the next one should be merged with the previous but keeping it separate is
@@ -447,6 +454,7 @@ end
local function stacked(attribute,head,default) -- no triggering, no inheritance, but list-wise
local stack = head
+ local done = false
local current = default or 0
local depth = 0
local check = false
@@ -464,30 +472,42 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
local content = getlist(stack)
if content then
-- the problem is that broken lines gets the attribute which can be a later one
- local list
if nslistwise then
local a = getattr(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,copy_node(nsdata[a]))
- list = stacked(attribute,content,current) -- two return values
+ local list = stacked(attribute,content,current) -- two return values
+ if content ~= list then
+ setlist(stack,list)
+ end
head, stack = insert_node_after(head,stack,copy_node(nsnone))
current = p
+ done = true
else
- list = stacked(attribute,content,current)
+ local list, ok = stacked(attribute,content,current)
+ if content ~= list then
+ setlist(stack,list) -- only if ok
+ end
+ if ok then
+ done = true
+ end
end
else
- list = stacked(attribute,content,current)
- end
- if content ~= list then
- setlist(stack,list) -- only if ok
+ local list, ok = stacked(attribute,content,current)
+ if content ~= list then
+ setlist(stack,list) -- only if ok
+ end
+ if ok then
+ done = true
+ end
end
end
elseif id == rule_code then
- local wd, ht, dp = getwhd(stack)
- check = wd ~= 0 or (ht+dp) ~= 0
+ check = getwidth(stack) ~= 0
end
+
if check then
local a = getattr(stack,attribute)
if a then
@@ -495,14 +515,15 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_before(head,stack,copy_node(nsdata[a]))
depth = depth + 1
current = a
+ done = true
end
if leader then
- local content = getlist(leader)
- if content then
- local list = stacked(attribute,content,current)
- if leader ~= list then
- setleader(stack,list) -- only if ok
- end
+ local list, ok = stacked(attribute,content,current)
+ if leader ~= list then
+ setleader(stack,list) -- only if ok
+ end
+ if ok then
+ done = true
end
leader = false
end
@@ -512,6 +533,7 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_before(head,stack,copy_node(nsnone))
depth = depth - 1
current = 0
+ done = true
end
check = false
end
@@ -521,22 +543,24 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_after(head,stack,copy_node(nsnone))
depth = depth - 1
end
- return head
+ return head, done
end
states.stacked = function(namespace,attribute,head,default)
- return stacked(attribute,head,default)
+ local head, done = stacked(attribute,tonut(head),default)
+ return tonode(head), done
end
-- experimental
local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise
- -- nsbegin()
+-- nsbegin()
local stacked = false
local current = head
local previous = head
+ local done = false
local attrib = default or unsetvalue
local check = false
local leader = false
@@ -552,27 +576,38 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
end
elseif id == hlist_code or id == vlist_code then
local content = getlist(current)
- if content then
- local list
- if nslistwise then
- local a = getattr(current,attribute)
- if a and attrib ~= a and nslistwise[a] then -- viewerlayer
- head = insert_node_before(head,current,copy_node(nsdata[a]))
- list = stacker(attribute,content,a)
- head, current = insert_node_after(head,current,copy_node(nsnone))
- else
- list = stacker(attribute,content,attrib)
+ if not content then
+ -- skip
+ elseif nslistwise then
+ local a = getattr(current,attribute)
+ if a and attrib ~= a and nslistwise[a] then -- viewerlayer
+ head = insert_node_before(head,current,copy_node(nsdata[a]))
+ local list = stacker(attribute,content,a)
+ if list ~= content then
+ setlist(current,list)
end
+ done = true
+ head, current = insert_node_after(head,current,copy_node(nsnone))
else
- list = stacker(attribute,content,default)
+ local list, ok = stacker(attribute,content,attrib)
+ if content ~= list then
+ setlist(current,list)
+ end
+ if ok then
+ done = true
+ end
end
+ else
+ local list, ok = stacker(attribute,content,default)
if list ~= content then
setlist(current,list)
end
+ if ok then
+ done = true
+ end
end
elseif id == rule_code then
- local wd, ht, dp = getwhd(current)
- check = wd ~= 0 or (ht+dp) ~= 0
+ check = getwidth(current) ~= 0
end
if check then
@@ -584,22 +619,16 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
end
local n = nsstep(a)
if n then
- head = insert_node_before(head,current,n) -- a
+ head = insert_node_before(head,current,tonut(n)) -- a
end
attrib = a
+ done = true
if leader then
-- tricky as a leader has to be a list so we cannot inject before
- -- local list = stacker(attribute,leader,attrib)
- -- leader = false
-
- local content = getlist(leader)
- if content then
- local list = stacker(attribute,leader,attrib)
- if leader ~= list then
- setleader(current,list)
- end
+ local list, ok = stacker(attribute,leader,attrib)
+ if ok then
+ done = true
end
-
leader = false
end
end
@@ -613,101 +642,18 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
if stacked then
local n = nsend()
while n do
- head = insert_node_after(head,previous,n)
+ head = insert_node_after(head,previous,tonut(n))
n = nsend()
end
end
- return head
+ return head, done
end
--- local nextid = nodes.nuts.traversers.id
---
--- local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise
---
--- -- nsbegin()
--- local stacked = false
---
--- local current = head
--- local previous = head
--- local attrib = default or unsetvalue
--- local check = false
--- local leader = false
---
--- local id = getid(current)
--- while current do
--- if id == glyph_code then
--- check = true
--- elseif id == glue_code then
--- leader = getleader(current)
--- if leader then
--- check = true
--- end
--- elseif id == hlist_code or id == vlist_code then
--- local content = getlist(current)
--- if content then
--- local list
--- if nslistwise then
--- local a = getattr(current,attribute)
--- if a and attrib ~= a and nslistwise[a] then -- viewerlayer
--- head = insert_node_before(head,current,copy_node(nsdata[a]))
--- list = stacker(attribute,content,a)
--- head, current = insert_node_after(head,current,copy_node(nsnone))
--- else
--- list = stacker(attribute,content,attrib)
--- end
--- else
--- list = stacker(attribute,content,default)
--- end
--- if list ~= content then
--- setlist(current,list)
--- end
--- end
--- elseif id == rule_code then
--- check = getwidth(current) ~= 0
--- end
---
--- if check then
--- local a = getattr(current,attribute) or unsetvalue
--- if a ~= attrib then
--- if not stacked then
--- stacked = true
--- nsbegin()
--- end
--- local n = nsstep(a)
--- if n then
--- head = insert_node_before(head,current,n) -- a
--- end
--- attrib = a
--- if leader then
--- -- tricky as a leader has to be a list so we cannot inject before
--- local list = stacker(attribute,leader,attrib)
--- leader = false
--- end
--- end
--- check = false
--- end
---
--- previous = current
---
--- current, id = nextid(current,current)
--- end
---
--- if stacked then
--- local n = nsend()
--- while n do
--- head = insert_node_after(head,previous,n)
--- n = nsend()
--- end
--- end
---
--- return head
--- end
-
states.stacker = function(namespace,attribute,head,default)
- local head = stacker(attribute,head,default)
+ local head, done = stacker(attribute,tonut(head),default)
nsreset()
- return head
+ return tonode(head), done
end
-- -- --