diff options
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.lua | 472 |
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 -- -- -- |