diff options
Diffstat (limited to 'tex/context/base/node-fin.lua')
-rw-r--r-- | tex/context/base/node-fin.lua | 716 |
1 files changed, 8 insertions, 708 deletions
diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua index 2e62ebcb5..63a5ef83e 100644 --- a/tex/context/base/node-fin.lua +++ b/tex/context/base/node-fin.lua @@ -41,93 +41,13 @@ local unsetvalue = attributes.unsetvalue -- these two will be like trackers -function states.enabletriggering() - triggering = true -end -function states.disabletriggering() - triggering = false -end - --- the following code is no longer needed due to the new backend --- but we keep it around for a while as an example --- --- states.collected = states.collected or { } --- --- storage.register("states/collected", states.collected, "states.collected") --- --- local collected = states.collected --- --- function states.collect(str) --- collected[#collected+1] = str --- end --- --- function states.flush() --- if #collected > 0 then --- for i=1,#collected do --- context(collected[i]) -- we're in context mode anyway --- end --- collected = { } --- states.collected = collected --- end --- end --- --- function states.check() --- logs.report("states",concat(collected,"\n")) --- end - --- we used to do the main processor loop here and call processor for each node --- but eventually this was too much a slow down (1 sec on 23 for 120 pages mk) --- so that we moved looping to the processor itself; this may lead to a bit of --- duplicate code once that we have more state handlers - --- local function process_attribute(head,plugin) -- head,attribute,enabled,initializer,resolver,processor,finalizer --- local namespace = plugin.namespace --- if namespace.enabled ~= false then -- this test will go away --- starttiming(attributes) -- in principle we could delegate this to the main caller --- local done, used, ok = false, nil, false --- local attribute = namespace.attribute or numbers[plugin.name] -- todo: plugin.attribute --- local processor = plugin.processor --- if processor then --- local initializer = plugin.initializer --- local resolver = plugin.resolver --- local inheritance = (resolver and resolver()) or nil -- -0x7FFFFFFF -- we can best use nil and skip ! --- if initializer then --- initializer(namespace,attribute,head) --- end --- head, ok = processor(namespace,attribute,head,inheritance) --- if ok then --- local finalizer = plugin.finalizer --- if finalizer then --- head, ok, used = finalizer(namespace,attribute,head) --- if used then --- local flusher = plugin.flusher --- if flusher then --- head = flusher(namespace,attribute,head,used) --- end --- end --- end --- done = true --- end --- end --- stoptiming(attributes) --- return head, done --- else --- return head, false --- end --- end --- --- function nodes.installattributehandler(plugin) -- we need to avoid this nested function --- return function(head) --- return process_attribute(head,plugin) --- end --- end - --- An experiment: lean and mean functions. It is not really faster but --- with upcoming functionality it might make a difference, e.g. features --- like 'casing' and 'italics' can be called a lot so there it makes sense. +function states.enabletriggering () triggering = true end +function states.disabletriggering() triggering = false end nodes.plugindata = nil +-- inheritance: -0x7FFFFFFF -- we can best use nil and skip ! + local template = [[ local plugin = nodes.plugindata local starttiming = statistics.starttiming @@ -146,8 +66,10 @@ if not processor then elseif initializer or finalizer or resolver then return function(head) starttiming(attributes) - local done, used, ok = false, nil, false - local inheritance = (resolver and resolver()) or nil -- -0x7FFFFFFF -- we can best use nil and skip ! + local done, used, ok, inheritance = false, nil, false, nil + if resolver then + inheritance = resolver() + end if initializer then initializer(namespace,attribute,head) end @@ -228,309 +150,6 @@ end -- 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 = 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 stack[nstrigger] then --- local outer = 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 stack[nstrigger] then --- local outer = 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 = 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 --- 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 --- return c --- end - --- local function nested(content) --- if nstrigger and stack[nstrigger] then --- local outer = 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 == 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) --- done = done or ok - --- end --- elseif id == rule_code then --- if stack.width ~= 0 then --- check() --- 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 --- while stack do --- local id = stack.id --- if id == glyph_code then --- -- begin of check --- local c = 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 --- 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 --- -- end of check --- elseif id == glue_code then --- local content = stack.leader --- if content then --- -- begin of check --- local c = 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 --- -- begin special to this check --- 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 --- -- begin nested -- --- local ok = false --- if nstrigger and stack[nstrigger] then --- local outer = 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 --- -- end nested -- --- done = done or ok --- current = savedcurrent --- -- end special to this check --- 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 --- -- end of check --- end --- elseif id == hlist_code or id == vlist_code then --- local content = stack.list --- if content then --- -- begin nested -- --- local ok --- if nstrigger and stack[nstrigger] then --- local outer = 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 --- -- end nested -- --- done = done or ok --- end --- elseif id == rule_code then --- if stack.width ~= 0 then --- -- begin of check --- local c = 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 --- 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 --- -- end of check --- end --- end --- stack = stack.next --- end --- return head, done --- end - local function process(namespace,attribute,head,inheritance,default) -- one attribute local stack = head local done = false @@ -633,184 +252,6 @@ 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 = 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 stack[nsselector] or nsselector])) --- current = default --- done = true --- end --- else --- local s = 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 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 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 stack[nstrigger] then --- local outer = 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 stack[nstrigger] then --- local outer = 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 = 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 stack[nsselector] or nsselector])) --- current = default --- done = true --- end --- else --- local s = 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 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 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 stack[nstrigger] then --- local outer = 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 == 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) --- done = done or ok - --- end --- elseif id == rule_code then --- if stack.width ~= 0 then --- check() --- end --- end --- stack = stack.next --- end --- return head, done --- end - local function selective(namespace,attribute,head,inheritance,default) -- two attributes local stack = head local done = false @@ -914,77 +355,6 @@ states.selective = selective -- 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 = 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 == 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 --- 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 = stack[attribute] --- if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below --- local p = current --- 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 ok = false --- stack.list, ok = stacked(namespace,attribute,content,current) --- done = done or ok --- end --- else --- local ok = false --- stack.list, ok = stacked(namespace,attribute,content,current) --- done = done or ok --- end --- end --- elseif id == rule_code then --- if stack.width ~= 0 then --- check() --- end --- end --- stack = stack.next --- end --- while depth > 0 do --- head = insert_node_after(head,stack,copy_node(nsnone)) --- depth = depth - 1 --- end --- return head, done --- end - local function stacked(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise local stack = head local done = false @@ -1066,76 +436,6 @@ 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 = 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 = 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 - local function stacker(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise nsbegin() local current = head |