diff options
author | Hans Hagen <pragma@wxs.nl> | 2018-05-12 01:19:03 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2018-05-12 01:19:03 +0200 |
commit | 77e216e323271fb85d508b7206b13c980540b74b (patch) | |
tree | 5b4053c2bbe5190e28c0dce89653c7b13aea0642 /tex/context/base/mkiv/node-fin.lua | |
parent | d817aef76ab8b606c02bd0636661b634b43a68a6 (diff) | |
download | context-77e216e323271fb85d508b7206b13c980540b74b.tar.gz |
2018-05-12 00:16:00
Diffstat (limited to 'tex/context/base/mkiv/node-fin.lua')
-rw-r--r-- | tex/context/base/mkiv/node-fin.lua | 465 |
1 files changed, 270 insertions, 195 deletions
diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua index 975eb0bec..f7e2c7904 100644 --- a/tex/context/base/mkiv/node-fin.lua +++ b/tex/context/base/mkiv/node-fin.lua @@ -16,7 +16,6 @@ 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 @@ -34,6 +33,8 @@ 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 @@ -44,6 +45,7 @@ local glue_code = nodecodes.glue local rule_code = nodecodes.rule local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist +local localpar_code = nodecodes.localpar local states = attributes.states local numbers = attributes.numbers @@ -82,37 +84,34 @@ local finalizer = plugin.finalizer local flusher = plugin.flusher if not processor then return function(head) - return head, false + return head end elseif initializer or finalizer or resolver then return function(head) starttiming(attributes) - local done, used, ok, inheritance = false, nil, false, nil + local used, inheritance if resolver then inheritance = resolver() end if initializer then initializer(namespace,attribute,head) end - 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 + 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) end - done = true end stoptiming(attributes) - return head, done + return head end else return function(head) starttiming(attributes) - local head, done = processor(namespace,attribute,head) + head = processor(namespace,attribute,head) stoptiming(attributes) - return head, done + return head end end nodes.plugindata = nil @@ -126,7 +125,7 @@ end -- the injectors local nsdata, nsnone, nslistwise, nsforced, nsselector, nstrigger -local current, current_selector, done = 0, 0, false -- nb, stack has a local current ! +local current, current_selector = 0, 0 -- nb, stack has a local current ! local nsbegin, nsend, nsreset function states.initialize(namespace,attribute,head) @@ -138,7 +137,6 @@ 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 @@ -151,7 +149,6 @@ 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) @@ -164,20 +161,114 @@ function states.finalize(namespace,attribute,head) -- is this one ok? else head = insert_node_before(head,head,copy_node(nsnone)) end - return tonode(head), true, true + return head, true end - return head, false, false + return head, 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 check = false +-- local leader = nil +-- 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 +-- leader = getleader(stack) +-- if leader then +-- check = true +-- end +-- elseif id == hlist_code or id == vlist_code then +-- local content = getlist(stack) +-- if content then +-- -- begin nested -- +-- local list +-- if nstrigger and getattr(stack,nstrigger) then +-- local outer = getattr(stack,attribute) +-- if outer ~= inheritance then +-- list = process(attribute,content,inheritance,outer) +-- else +-- list = process(attribute,content,inheritance,default) +-- end +-- else +-- list = process(attribute,content,inheritance,default) +-- end +-- if content ~= list then +-- setlist(stack,list) +-- end +-- -- end nested -- +-- end +-- elseif id == rule_code then +-- check = getwidth(stack) ~= 0 +-- end +-- -- much faster this way than using a check() and nested() function +-- if check then +-- local c = getattr(stack,attribute) +-- if c then +-- if default and c == inheritance then +-- if current ~= default then +-- head = insert_node_before(head,stack,copy_node(nsdata[default])) +-- current = default +-- end +-- elseif current ~= c then +-- head = insert_node_before(head,stack,copy_node(nsdata[c])) +-- current = c +-- end +-- if leader then +-- local savedcurrent = current +-- local ci = getid(leader) +-- 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 +-- -- for improvement here +-- 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) +-- else +-- list = process(attribute,leader,inheritance,default) +-- end +-- else +-- list = process(attribute,leader,inheritance,default) +-- end +-- if leader ~= list then +-- setleader(stack,list) +-- end +-- -- end nested -- +-- current = savedcurrent +-- leader = false +-- 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 +-- check = false +-- end +-- stack = getnext(stack) +-- end +-- return head +-- end +-- +-- states.process = function(namespace,attribute,head,default) +-- return process(attribute,head,default) +-- end + local function process(attribute,head,inheritance,default) -- one attribute - local stack = head - local done = false local check = false local leader = nil - while stack do - local id = getid(stack) + for stack, id in nextnode, head do if id == glyph_code or id == disc_code then check = true -- disc no longer needed as we flatten replace elseif id == glue_code then @@ -189,33 +280,19 @@ local function process(attribute,head,inheritance,default) -- one attribute local content = getlist(stack) if content then -- begin nested -- + local list if nstrigger and getattr(stack,nstrigger) then local outer = getattr(stack,attribute) if outer ~= inheritance then - local list, ok = process(attribute,content,inheritance,outer) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = process(attribute,content,inheritance,outer) else - local list, ok = process(attribute,content,inheritance,default) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = process(attribute,content,inheritance,default) end else - local list, ok = process(attribute,content,inheritance,default) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = process(attribute,content,inheritance,default) + end + if content ~= list then + setlist(stack,list) end -- end nested -- end @@ -230,12 +307,10 @@ 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 @@ -247,33 +322,19 @@ 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 - local list, ok = process(attribute,leader,inheritance,outer) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = process(attribute,leader,inheritance,outer) else - local list, ok = process(attribute,leader,inheritance,default) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = process(attribute,leader,inheritance,default) end else - local list, ok = process(attribute,leader,inheritance,default) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = process(attribute,leader,inheritance,default) + end + if leader ~= list then + setleader(stack,list) end -- end nested -- current = savedcurrent @@ -283,23 +344,19 @@ 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, done + return head end states.process = function(namespace,attribute,head,default) - local head, done = process(attribute,tonut(head),default) - return tonode(head), done + return process(attribute,head,default) end -- we can force a selector, e.g. document wide color spaces, saves a little @@ -308,14 +365,106 @@ end -- state changes while the main state stays the same (like two glyphs following -- each other with the same color but different color spaces e.g. \showcolor) +-- local function selective(attribute,head,inheritance,default) -- two attributes +-- local stack = head +-- local check = false +-- local leader = nil +-- 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 +-- leader = getleader(stack) +-- if leader then +-- check = true +-- end +-- elseif id == hlist_code or id == vlist_code then +-- local content = getlist(stack) +-- if content then +-- -- begin nested +-- local list +-- if nstrigger and getattr(stack,nstrigger) then +-- local outer = getattr(stack,attribute) +-- if outer ~= inheritance then +-- list = selective(attribute,content,inheritance,outer) +-- else +-- list = selective(attribute,content,inheritance,default) +-- end +-- else +-- list = selective(attribute,content,inheritance,default) +-- end +-- if content ~= list then +-- setlist(stack,list) +-- end +-- -- end nested +-- end +-- elseif id == rule_code then +-- check = getwidth(stack) ~= 0 +-- end +-- +-- if check then +-- local c = getattr(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,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 ~= c or current_selector ~= s then +-- local data = nsdata[c] +-- head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector])) +-- current = c +-- current_selector = s +-- 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) +-- else +-- list = selective(attribute,leader,inheritance,default) +-- end +-- else +-- list = selective(attribute,leader,inheritance,default) +-- end +-- if leader ~= list then +-- setleader(stack,list) +-- end +-- -- end nested +-- leader = false +-- 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 +-- check = false +-- end +-- stack = getnext(stack) +-- end +-- return head +-- end +-- +-- states.selective = function(namespace,attribute,head,default) +-- return selective(attribute,head,default) +-- end + local function selective(attribute,head,inheritance,default) -- two attributes - -- local head = head - local stack = head - local done = false local check = false local leader = nil - while stack do - local id = getid(stack) + for stack, id in nextnode, head do if id == glyph_code or id == disc_code then check = true -- disc no longer needed as we flatten replace elseif id == glue_code then @@ -327,33 +476,19 @@ local function selective(attribute,head,inheritance,default) -- two attributes local content = getlist(stack) if content then -- begin nested + local list if nstrigger and getattr(stack,nstrigger) then local outer = getattr(stack,attribute) if outer ~= inheritance then - local list, ok = selective(attribute,content,inheritance,outer) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = selective(attribute,content,inheritance,outer) else - local list, ok = selective(attribute,content,inheritance,default) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = selective(attribute,content,inheritance,default) end else - local list, ok = selective(attribute,content,inheritance,default) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = selective(attribute,content,inheritance,default) + end + if content ~= list then + setlist(stack,list) end -- end nested end @@ -369,9 +504,6 @@ 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) @@ -379,43 +511,25 @@ 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 - local list, ok = selective(attribute,leader,inheritance,outer) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = selective(attribute,leader,inheritance,outer) else - local list, ok = selective(attribute,leader,inheritance,default) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = selective(attribute,leader,inheritance,default) end else - local list, ok = selective(attribute,leader,inheritance,default) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = selective(attribute,leader,inheritance,default) + end + if leader ~= list then + setleader(stack,list) end -- end nested leader = false @@ -425,22 +539,19 @@ 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, done = 0, 0, true + current, current_selector = 0, 0 end check = false end - stack = getnext(stack) end - return head, done + return head end states.selective = function(namespace,attribute,head,default) - local head = selective(attribute,tonut(head),default) - return tonode(head), true + return selective(attribute,head,default) end -- Ideally the next one should be merged with the previous but keeping it separate is @@ -454,7 +565,6 @@ 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 @@ -472,36 +582,24 @@ 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])) - local list = stacked(attribute,content,current) -- two return values - if content ~= list then - setlist(stack,list) - end + list = stacked(attribute,content,current) -- two return values head, stack = insert_node_after(head,stack,copy_node(nsnone)) current = p - done = true else - local list, ok = stacked(attribute,content,current) - if content ~= list then - setlist(stack,list) -- only if ok - end - if ok then - done = true - end + list = stacked(attribute,content,current) end else - local list, ok = stacked(attribute,content,current) - if content ~= list then - setlist(stack,list) -- only if ok - end - if ok then - done = true - end + list = stacked(attribute,content,current) + end + if content ~= list then + setlist(stack,list) -- only if ok end end elseif id == rule_code then @@ -515,16 +613,12 @@ 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 list, ok = stacked(attribute,content,current) + local list = stacked(attribute,content,current) if leader ~= list then setleader(stack,list) -- only if ok end - if ok then - done = true - end leader = false end elseif default > 0 then @@ -533,7 +627,6 @@ 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 @@ -543,24 +636,22 @@ 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, done + return head end states.stacked = function(namespace,attribute,head,default) - local head, done = stacked(attribute,tonut(head),default) - return tonode(head), done + return stacked(attribute,head,default) 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 @@ -576,35 +667,23 @@ 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 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) + 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 - done = true - head, current = insert_node_after(head,current,copy_node(nsnone)) else - local list, ok = stacker(attribute,content,attrib) - if content ~= list then - setlist(current,list) - end - if ok then - done = true - end + list = stacker(attribute,content,default) 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 check = getwidth(current) ~= 0 @@ -622,13 +701,9 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, 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, ok = stacker(attribute,leader,attrib) - if ok then - done = true - end + local list = stacker(attribute,leader,attrib) leader = false end end @@ -647,13 +722,13 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, end end - return head, done + return head end states.stacker = function(namespace,attribute,head,default) - local head, done = stacker(attribute,tonut(head),default) + local head = stacker(attribute,head,default) nsreset() - return tonode(head), done + return head end -- -- -- |