summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/node-mig.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/node-mig.lua')
-rw-r--r--tex/context/base/mkiv/node-mig.lua227
1 files changed, 122 insertions, 105 deletions
diff --git a/tex/context/base/mkiv/node-mig.lua b/tex/context/base/mkiv/node-mig.lua
index 6c10625eb..13414c560 100644
--- a/tex/context/base/mkiv/node-mig.lua
+++ b/tex/context/base/mkiv/node-mig.lua
@@ -14,157 +14,174 @@ local trace_migrations = false trackers.register("nodes.migrations", function(v)
local report_nodes = logs.reporter("nodes","migrations")
-local attributes = attributes
-local nodes = nodes
-local enableaction = nodes.tasks.enableaction
+local attributes = attributes
+local nodes = nodes
-local nuts = nodes.nuts
-local tonut = nuts.tonut
+local nuts = nodes.nuts
+local tonut = nuts.tonut
-local getnext = nuts.getnext
-local getid = nuts.getid
-local getlist = nuts.getlist
------ getattr = nuts.getattr
-local getprop = nuts.getprop
+local getnext = nuts.getnext
+local getid = nuts.getid
+local getlist = nuts.getlist
+local getprop = nuts.getprop
------ setattr = nuts.setattr
-local setprop = nuts.setprop
-local setlink = nuts.setlink
-local setlist = nuts.setlist
-local setprev = nuts.setprev
-local setnext = nuts.setnext
-local setboth = nuts.setboth
+local setprop = nuts.setprop
+local setlink = nuts.setlink
+local setlist = nuts.setlist
+local setprev = nuts.setprev
+local setnext = nuts.setnext
+local setboth = nuts.setboth
-local remove_node = nuts.remove
+local remove_node = nuts.remove
+local count = nuts.count
-local nodecodes = nodes.nodecodes
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local insert_code = nodecodes.ins
-local mark_code = nodecodes.mark
+local nodecodes = nodes.nodecodes
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local insert_code = nodecodes.ins
+local mark_code = nodecodes.mark
-local a_migrated = attributes.private("migrated")
+local a_migrated = attributes.private("migrated")
+local trialtypesetting = context.trialtypesetting
-local migrate_inserts, migrate_marks, inserts_too
+local migrate_inserts = false
+local migrate_marks = false
-local t_inserts, t_marks, t_sweeps = 0, 0, 0
+local t_inserts = 0
+local t_marks = 0
+local t_sweeps = 0
-local function locate(head,first,last,ni,nm)
+local function locate(head,first,last)
local current = head
while current do
local id = getid(current)
if id == vlist_code or id == hlist_code then
local list = getlist(current)
if list then
- list, first, last, ni, nm = locate(list,first,last,ni,nm)
- setlist(current,list)
+ local l
+ l, first, last = locate(list,first,last)
+ if l ~= list then
+ setlist(current,l)
+ end
end
current = getnext(current)
- elseif migrate_inserts and id == insert_code then
- local insert
- head, current, insert = remove_node(head,current)
- if first then
- setnext(insert)
- setlink(last,insert)
- else
- setboth(insert)
- first = insert
+ elseif id == insert_code then
+ if migrate_inserts then
+ local insert
+ head, current, insert = remove_node(head,current)
+ if first then
+ setnext(insert)
+ setlink(last,insert)
+ else
+ setboth(insert)
+ first = insert
+ end
+ last = insert
end
- last = insert
- ni = ni + 1
- elseif migrate_marks and id == mark_code then
- local mark
- head, current, mark = remove_node(head,current)
- if first then
- setnext(mark)
- setlink(last,mark)
- else
- setboth(mark)
- first = mark
+ elseif id == mark_code then
+ if migrate_marks then
+ local mark
+ head, current, mark = remove_node(head,current)
+ if first then
+ setnext(mark)
+ setlink(last,mark)
+ else
+ setboth(mark)
+ first = mark
+ end
+ last = mark
end
- last = mark
- nm = nm + 1
else
current = getnext(current)
end
end
- return head, first, last, ni, nm
+ return head, first, last
end
function nodes.handlers.migrate(head,where)
- if head then
+ if head and not trialtypesetting() then
if trace_migrations then
report_nodes("migration sweep %a",where)
end
local current = head
while current do
local id = getid(current)
- -- inserts_too is a temp hack, we should only do them when it concerns
- -- newly placed (flushed) inserts
-
- -- todo: getprop / setprop
-
- -- if id == vlist_code or id == hlist_code or (inserts_too and id == insert_code) and not getattr(current,a_migrated) then
- if id == vlist_code or id == hlist_code or (inserts_too and id == insert_code) and not getprop(current,"migrated") then
- -- setattr(current,a_migrated,1)
+ if (id == vlist_code or id == hlist_code or id == insert_code) and not getprop(current,"migrated") then
setprop(current,"migrated",true)
- t_sweeps = t_sweeps + 1
local h = getlist(current)
- local first, last, ni, nm
- while h do
- local id = getid(h)
- if id == vlist_code or id == hlist_code then
- h, first, last, ni, nm = locate(h,first,last,0,0)
+ if h then
+ t_sweeps = t_sweeps + 1
+ local first, last
+ while h do
+ local id = getid(h)
+ if id == vlist_code or id == hlist_code then
+ h, first, last = locate(h,first,last)
+ end
+ h = getnext(h)
end
- h = getnext(h)
- end
- if first then
- t_inserts = t_inserts + ni
- t_marks = t_marks + nm
- if trace_migrations and (ni > 0 or nm > 0) then
- report_nodes("sweep %a, container %a, %s inserts and %s marks migrated outwards during %a",
- t_sweeps,nodecodes[id],ni,nm,where)
- end
- -- inserts after head, use insert_after
- local n = getnext(current)
- if n then
- setlink(last,n)
+ if first then
+ if trace_migrations then
+ local ni = count(insert_code,first)
+ local nm = count(mark_code,first)
+ t_inserts = t_inserts + ni
+ t_marks = t_marks + nm
+ report_nodes("sweep %a, container %a, %s inserts and %s marks migrated outwards during %a",
+ t_sweeps,nodecodes[id],ni,nm,where)
+ end
+ local n = getnext(current)
+ if n then
+ setlink(last,n)
+ end
+ setlink(current,first)
+ current = last
end
- setlink(current,first)
- current = last
end
end
current = getnext(current)
end
- return head
end
+ return head
end
--- for the moment this way, this will disappear
-
-experiments.register("marks.migrate", function(v)
- if v then
- enableaction("mvlbuilders", "nodes.handlers.migrate")
+statistics.register("node migrations", function()
+ if trace_migrations and t_sweeps > 0 then
+ return format("%s sweeps, %s inserts moved, %s marks moved",t_sweeps,t_inserts,t_marks)
end
- migrate_marks = v
end)
-experiments.register("inserts.migrate", function(v)
- if v then
- enableaction("mvlbuilders", "nodes.handlers.migrate")
- end
- migrate_inserts = v
-end)
+-- Since we started with mkiv we had it as experiment but it is about time
+-- to have a more formal interface .. it's still optional due to possible
+-- side effects.
-experiments.register("inserts.migrate.nested", function(v)
- if v then
- enableaction("mvlbuilders", "nodes.handlers.migrate")
+local enableaction = nodes.tasks.enableaction
+local disableaction = nodes.tasks.disableaction
+
+local migrations = { }
+nodes.migrations = migrations
+local enabled = false
+
+local function check()
+ if migrate_marks or migrate_inserts then
+ if not enabled then
+ enableaction("mvlbuilders", "nodes.handlers.migrate")
+ enableaction("processors", "nodes.handlers.migrate")
+ enabled = true
+ end
+ else
+ if enabled then
+ disableaction("mvlbuilders", "nodes.handlers.migrate")
+ disableaction("processors", "nodes.handlers.migrate")
+ enabled = false
+ end
end
- inserts_too = v
-end)
+end
-statistics.register("node migrations", function()
- if trace_migrations and t_sweeps > 0 then
- return format("%s sweeps, %s inserts moved, %s marks moved",t_sweeps,t_inserts,t_marks)
- end
-end)
+function migrations.setmarks(v)
+ migrate_marks = v
+ check()
+end
+
+function migrations.setinserts(v)
+ migrate_inserts = v
+ check()
+end