summaryrefslogtreecommitdiff
path: root/tex/context/base/node-fin.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/node-fin.lua')
-rw-r--r--tex/context/base/node-fin.lua98
1 files changed, 79 insertions, 19 deletions
diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua
index a801e9acb..e83a354f2 100644
--- a/tex/context/base/node-fin.lua
+++ b/tex/context/base/node-fin.lua
@@ -74,11 +74,11 @@ end
-- duplicate code once that we have more state handlers
local function process_attribute(head,plugin) -- head,attribute,enabled,initializer,resolver,processor,finalizer
- starttiming(attributes)
- local done, used, ok = false, nil, false
- local attribute = numbers[plugin.name] -- todo: plugin.attribute
local namespace = plugin.namespace
if namespace.enabled then
+ starttiming(attributes)
+ 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
@@ -102,19 +102,69 @@ local function process_attribute(head,plugin) -- head,attribute,enabled,initiali
done = true
end
end
+ stoptiming(attributes)
+ return head, done
+ else
+ return head, false
end
- stoptiming(attributes)
- return head, done
end
nodes.process_attribute = process_attribute
-function nodes.install_attribute_handler(plugin)
+function nodes.install_attribute_handler(plugin) -- we need to avoid this nested function
return function(head)
return process_attribute(head,plugin)
end
end
+--~ experiment (maybe local to function makes more sense)
+--~
+--~ plugindata = { }
+--~
+--~ local template = [[
+--~ local plugin = plugindata["%s"]
+--~ local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+--~ local namespace = plugin.namespace
+--~ local attribute = namespace.attribute
+--~ local processor = plugin.processor
+--~ local initializer = plugin.initializer
+--~ local resolver = plugin.resolver
+--~ local finalizer = plugin.finalizer
+--~ local flusher = plugin.flusher
+--~ return function (head)
+--~ if namespace.enabled then
+--~ starttiming(attributes)
+--~ local done, used, ok = false, nil, false
+--~ if procesxsor then
+--~ 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
+--~ 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
+--~ end
+--~ stoptiming(attributes)
+--~ return head, done
+--~ else
+--~ return head, false
+--~ end
+--~ end
+--~ ]]
+--~
+--~ function nodes.install_attribute_handler(plugin) -- we need to avoid this nested function
+--~ plugindata[plugin.name] = plugin
+--~ local str = format(template,plugin.name)
+--~ return loadstring(str)()
+--~ end
+
-- the injectors
local insert_node_before = node.insert_before
@@ -125,7 +175,7 @@ local current, current_selector, done = 0, 0, false -- nb, stack has a local cur
function states.initialize(namespace,attribute,head)
nsdata, nsnone = namespace.data, namespace.none
- nsforced, nsselector = namespace.forced, namespace.selector
+ nsforced, nsselector, nslistwise = namespace.forced, namespace.selector, namespace.listwise
nstrigger = triggering and namespace.triggering and trigger
current, current_selector, done = 0, 0, false -- todo: done cleanup
end
@@ -315,12 +365,15 @@ end
states.selective = selective
--- todo: each line now gets the (e.g. layer) property, hard to avoid (and not needed too)
+-- 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 getsmixed up. A messy business (esp since we want to be
+-- efficient).
local function stacked(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise
local stack, done = head, false
---~ local current, depth = 0, 0
-local current, depth = default or 0, 0
+ local current, depth = default or 0, 0
while stack do
local id = stack.id
if id == glyph or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc
@@ -349,14 +402,21 @@ local current, depth = default or 0, 0
elseif id == hlist or id == vlist then
local content = stack.list
if content then
- local c = has_attribute(stack,attribute)
- if c and current ~= c then
- local p = current
- 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
+ -- the problem is that broken lines gets the attribute which can be a later one
+ if nslistwise then
+ local c = has_attribute(stack,attribute)
+ if c and current ~= c and nslistwise[c] then -- viewerlayer
+ local p = current
+ 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
+ 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)
@@ -379,6 +439,6 @@ states.stacked = stacked
statistics.register("attribute processing time", function()
if statistics.elapsedindeed(attributes) then
- return format("%s seconds",statistics.elapsedtime(attributes))
+ return format("%s seconds (front- and backend)",statistics.elapsedtime(attributes))
end
end)