diff options
Diffstat (limited to 'tex/context/base/node-fin.lua')
-rw-r--r-- | tex/context/base/node-fin.lua | 591 |
1 files changed, 154 insertions, 437 deletions
diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua index 27793716d..5c1cc9ad5 100644 --- a/tex/context/base/node-fin.lua +++ b/tex/context/base/node-fin.lua @@ -7,7 +7,6 @@ if not modules then modules = { } end modules ['node-fin'] = { } -- this module is being reconstructed --- local functions, only slightly slower local next, type, format = next, type, string.format @@ -15,7 +14,6 @@ local attributes, nodes, node = attributes, nodes, node local has_attribute = node.has_attribute local copy_node = node.copy -local find_tail = node.slide local nodecodes = nodes.nodecodes local whatcodes = nodes.whatcodes @@ -38,8 +36,6 @@ local triggering = false local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming -local unsetvalue = attributes.unsetvalue - -- these two will be like trackers function states.enabletriggering() @@ -180,7 +176,6 @@ 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 function states.initialize(namespace,attribute,head) nsdata = namespace.data @@ -192,13 +187,6 @@ function states.initialize(namespace,attribute,head) current = 0 current_selector = 0 done = false -- todo: done cleanup - nsstep = namespace.resolve_step - if nsstep then - nsbegin = namespace.resolve_begin - nsend = namespace.resolve_end - nspush = namespace.push - nspop = namespace.pop - end end function states.finalize(namespace,attribute,head) -- is this one ok? @@ -217,167 +205,81 @@ function states.finalize(namespace,attribute,head) -- is this one ok? 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 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, done = head, false --- while stack do --- local id = stack.id --- if id == glyph_code or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code --- local c = has_attribute(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 --- done = true --- end --- elseif current ~= c then --- head = insert_node_before(head,stack,copy_node(nsdata[c])) --- current = c --- done = true --- end --- -- here ? compare selective --- if id == glue_code then --leader --- -- same as *list --- local content = stack.leader --- if content then --- local savedcurrent = current --- local ci = content.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 --- -- for improvement here --- current = 0 --- end --- local ok = false --- if nstrigger and has_attribute(stack,nstrigger) then --- local outer = has_attribute(stack,attribute) --- if outer ~= inheritance then --- stack.leader, ok = process(namespace,attribute,content,inheritance,outer) --- else --- stack.leader, ok = process(namespace,attribute,content,inheritance,default) --- end --- else --- stack.leader, ok = process(namespace,attribute,content,inheritance,default) --- end --- current = savedcurrent --- done = done or ok --- end --- end --- elseif default and inheritance then --- 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 --- elseif id == hlist_code or id == vlist_code then --- local content = stack.list --- if content then --- local ok = false --- if nstrigger and has_attribute(stack,nstrigger) then --- local outer = has_attribute(stack,attribute) --- if outer ~= inheritance then --- stack.list, ok = process(namespace,attribute,content,inheritance,outer) --- else --- stack.list, ok = process(namespace,attribute,content,inheritance,default) --- end --- else --- stack.list, ok = process(namespace,attribute,content,inheritance,default) --- end --- done = done or ok --- end --- end --- stack = stack.next --- end --- return head, done --- end - local function process(namespace,attribute,head,inheritance,default) -- one attribute local stack, done = head, false - - local function check() - local c = has_attribute(stack,attribute) - if c then - if default and c == inheritance then + while stack do + local id = stack.id + -- we need to deal with literals too (reset as well as oval) + -- 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 -- or disc_code + if id == glyph_code -- or id == disc_code + or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code + local c = has_attribute(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 + done = true + end + elseif current ~= c then + head = insert_node_before(head,stack,copy_node(nsdata[c])) + current = c + done = true + end + -- here ? compare selective + if id == glue_code then --leader + -- same as *list + local content = stack.leader + if content then + local savedcurrent = current + local ci = content.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 + -- for improvement here + current = 0 + end + local ok = false + if nstrigger and has_attribute(stack,nstrigger) then + local outer = has_attribute(stack,attribute) + if outer ~= inheritance then + stack.leader, ok = process(namespace,attribute,content,inheritance,outer) + else + stack.leader, ok = process(namespace,attribute,content,inheritance,default) + end + else + stack.leader, ok = process(namespace,attribute,content,inheritance,default) + end + current = savedcurrent + done = done or ok + end + end + elseif default and inheritance then 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 - elseif default and inheritance then - if current ~= default then - head = insert_node_before(head,stack,copy_node(nsdata[default])) - current = default + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + current = 0 done = true end - elseif current > 0 then - head = insert_node_before(head,stack,copy_node(nsnone)) - current = 0 - done = true - end - return c - end - - local function nested(content) - if nstrigger and has_attribute(stack,nstrigger) then - local outer = has_attribute(stack,attribute) - if outer ~= inheritance then - return process(namespace,attribute,content,inheritance,outer) - else - return process(namespace,attribute,content,inheritance,default) - end - else - return process(namespace,attribute,content,inheritance,default) - end - end - - while stack do - local id = stack.id - if id == glyph_code then - check() - elseif id == rule_code then - if stack.width ~= 0 then - check() - end - elseif id == glue_code then - local content = stack.leader - if content and check() then - local savedcurrent = current - local ci = content.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 - -- for improvement here - current = 0 - end - - local ok = false - stack.leader, ok = nested(content) - done = done or ok - - current = savedcurrent - end elseif id == hlist_code or id == vlist_code then local content = stack.list if content then - local ok = false - stack.list, ok = nested(content) + if nstrigger and has_attribute(stack,nstrigger) then + local outer = has_attribute(stack,attribute) + if outer ~= inheritance then + stack.list, ok = process(namespace,attribute,content,inheritance,outer) + else + stack.list, ok = process(namespace,attribute,content,inheritance,default) + end + else + stack.list, ok = process(namespace,attribute,content,inheritance,default) + end done = done or ok - end end stack = stack.next @@ -393,185 +295,86 @@ states.process = process -- 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(namespace,attribute,head,inheritance,default) -- two attributes --- local stack, done = head, false --- while stack do --- local id = stack.id --- -- we need to deal with literals too (reset as well as oval) --- -- 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 -- or disc_code --- if id == glyph_code -- or id == disc_code --- or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code --- local c = has_attribute(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 has_attribute(stack,nsselector) or nsselector])) --- current = default --- done = true --- end --- else --- local s = has_attribute(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 has_attribute(stack,nsselector) or nsselector])) --- current = c --- current_selector = s --- done = true --- 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 has_attribute(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 --- end --- if id == glue_code then -- leader --- -- same as *list --- local content = stack.leader --- if content then --- local savedcurrent = current --- local ci = content.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 --- -- for improvement here --- current = 0 --- end --- local ok = false --- if nstrigger and has_attribute(stack,nstrigger) then --- local outer = has_attribute(stack,attribute) --- if outer ~= inheritance then --- stack.leader, ok = selective(namespace,attribute,content,inheritance,outer) --- else --- stack.leader, ok = selective(namespace,attribute,content,inheritance,default) --- end --- else --- stack.leader, ok = selective(namespace,attribute,content,inheritance,default) --- end --- current = savedcurrent --- done = done or ok --- end --- end --- elseif id == hlist_code or id == vlist_code then --- local content = stack.list --- if content then --- local ok = false --- if nstrigger and has_attribute(stack,nstrigger) then --- local outer = has_attribute(stack,attribute) --- if outer ~= inheritance then --- stack.list, ok = selective(namespace,attribute,content,inheritance,outer) --- else --- stack.list, ok = selective(namespace,attribute,content,inheritance,default) --- end --- else --- stack.list, ok = selective(namespace,attribute,content,inheritance,default) --- end --- done = done or ok --- end --- end --- stack = stack.next --- end --- return head, done --- end - local function selective(namespace,attribute,head,inheritance,default) -- two attributes local stack, done = head, false - - local function check() - local c = has_attribute(stack,attribute) - if c then - if default and c == inheritance then + while stack do + local id = stack.id + -- we need to deal with literals too (reset as well as oval) + -- 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 -- or disc_code + if id == glyph_code -- or id == disc_code + or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code + local c = has_attribute(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 has_attribute(stack,nsselector) or nsselector])) + current = default + done = true + end + else + local s = has_attribute(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 has_attribute(stack,nsselector) or nsselector])) + current = c + current_selector = s + done = true + 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 has_attribute(stack,nsselector) or nsselector])) current = default done = true end - else - local s = has_attribute(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 has_attribute(stack,nsselector) or nsselector])) - current = c - current_selector = s - done = true - 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 has_attribute(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 - end - return c - end - - local function nested(content) - if nstrigger and has_attribute(stack,nstrigger) then - local outer = has_attribute(stack,attribute) - if outer ~= inheritance then - return selective(namespace,attribute,content,inheritance,outer) - else - return selective(namespace,attribute,content,inheritance,default) - end - else - return selective(namespace,attribute,content,inheritance,default) - end - end - - while stack do - local id = stack.id - if id == glyph_code then - check() - elseif id == rule_code then - if stack.width ~= 0 then - check() + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + current, current_selector, done = 0, 0, true end - elseif id == glue_code then - local content = stack.leader - if content and check() then - local savedcurrent = current - local ci = content.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 - -- for improvement here - current = 0 + if id == glue_code then -- leader + -- same as *list + local content = stack.leader + if content then + local savedcurrent = current + local ci = content.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 + -- for improvement here + current = 0 + end + local ok = false + if nstrigger and has_attribute(stack,nstrigger) then + local outer = has_attribute(stack,attribute) + if outer ~= inheritance then + stack.leader, ok = selective(namespace,attribute,content,inheritance,outer) + else + stack.leader, ok = selective(namespace,attribute,content,inheritance,default) + end + else + stack.leader, ok = selective(namespace,attribute,content,inheritance,default) + end + current = savedcurrent + done = done or ok end - - local ok = false - stack.leader, ok = nested(content) - done = done or ok - - current = savedcurrent end elseif id == hlist_code or id == vlist_code then local content = stack.list if content then - local ok = false - stack.list, ok = nested(content) + if nstrigger and has_attribute(stack,nstrigger) then + local outer = has_attribute(stack,attribute) + if outer ~= inheritance then + stack.list, ok = selective(namespace,attribute,content,inheritance,outer) + else + stack.list, ok = selective(namespace,attribute,content,inheritance,default) + end + else + stack.list, ok = selective(namespace,attribute,content,inheritance,default) + end done = done or ok - - -- nicer: - -- - -- local content, ok = nested(content) - -- if ok then - -- stack.leader = content - -- done = true - -- end - end end stack = stack.next @@ -579,65 +382,53 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at return 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 -- (as used in the stepper). In the stepper we cannot use the box branch as it involves --- paragraph lines and then gets mixed up. A messy business (esp since we want to be +-- paragraph lines and then getsmixed up. A messy business (esp since we want to be -- efficient). --- --- Todo: make a better stacker. Keep track (in attribute) about nesting level. Not --- entirely trivial and a generic solution is nicer (compares to the exporter). local function stacked(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise local stack, done = head, false local current, depth = default or 0, 0 - - local function check() - local a = has_attribute(stack,attribute) - if a then - if current ~= a then - head = insert_node_before(head,stack,copy_node(nsdata[a])) - depth = depth + 1 - current, done = a, true - end - elseif default > 0 then - -- - elseif current > 0 then - head = insert_node_before(head,stack,copy_node(nsnone)) - depth = depth - 1 - current, done = 0, true - end - return a - end - while stack do local id = stack.id - if id == glyph_code then - check() - elseif id == rule_code then - if stack.width ~= 0 then - check() - end - elseif id == glue_code then - local content = stack.leader - if content and check() then - local ok = false - stack.leader, ok = stacked(namespace,attribute,content,current) - done = done or ok + if id == glyph_code or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code + local c = has_attribute(stack,attribute) + if c then + if current ~= c then + head = insert_node_before(head,stack,copy_node(nsdata[c])) + depth = depth + 1 + current, done = c, true + end + if id == glue_code then + local content = stack.leader + if content then -- unchecked + local ok = false + stack.leader, ok = stacked(namespace,attribute,content,current) + done = done or ok + end + end +--~ elseif default then + elseif default > 0 then + -- + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + depth = depth - 1 + current, done = 0, true end elseif id == hlist_code or id == vlist_code then 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 = has_attribute(stack,attribute) - if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below + local c = has_attribute(stack,attribute) + if c and current ~= c and nslistwise[c] then -- viewerlayer local p = current - current, done = a, true - head = insert_node_before(head,stack,copy_node(nsdata[a])) + current, done = c, true + head = insert_node_before(head,stack,copy_node(nsdata[c])) stack.list = stacked(namespace,attribute,content,current) head, stack = insert_node_after(head,stack,copy_node(nsnone)) current = p @@ -657,87 +448,13 @@ local function stacked(namespace,attribute,head,default) -- no triggering, no in end while depth > 0 do head = insert_node_after(head,stack,copy_node(nsnone)) - depth = depth - 1 + depth = depth -1 end return head, done end states.stacked = stacked --- experimental - -local function stacker(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise - nsbegin() - local current, previous, done, okay = head, head, false, false - local attrib = default or unsetvalue - - local function check() - local a = has_attribute(current,attribute) or unsetvalue - if a ~= attrib then - local n = nsstep(a) - if n then - -- !!!! TEST CODE !!!! --- 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 - end - return a - end - - while current do - local id = current.id - if id == glyph_code then - check() - elseif id == glue_code then - local content = current.leader - if content and check() then - -- tricky as a leader has to be a list so we cannot inject before - local _, ok = stacker(namespace,attribute,content,attrib) - done = done or ok - end - elseif id == hlist_code or id == vlist_code then - local content = current.list - if not content then - -- skip - elseif nslistwise then - local a = has_attribute(current,attribute) - if a and attrib ~= a and nslistwise[a] then -- viewerlayer - done = true - 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 ok = false - current.list, ok = stacker(namespace,attribute,content,attrib) - done = done or ok - end - else - local ok = false - current.list, ok = stacker(namespace,attribute,content,default) - done = done or ok - end - elseif id == rule_code then - if current.width ~= 0 then - check() - end - end - previous = current - current = current.next - end - if okay then - local n = nsend() - if n then - -- !!!! TEST CODE !!!! --- 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 = stacker - -- -- -- statistics.register("attribute processing time", function() |