diff options
Diffstat (limited to 'tex/context/base/node-shp.lua')
-rw-r--r-- | tex/context/base/node-shp.lua | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/tex/context/base/node-shp.lua b/tex/context/base/node-shp.lua index 32024e5da..6ebfd767f 100644 --- a/tex/context/base/node-shp.lua +++ b/tex/context/base/node-shp.lua @@ -14,6 +14,7 @@ local concat, sortedpairs = table.concat, table.sortedpairs local setmetatableindex = table.setmetatableindex local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes local tasks = nodes.tasks local handlers = nodes.handlers @@ -23,6 +24,7 @@ local disc_code = nodecodes.disc local mark_code = nodecodes.mark local kern_code = nodecodes.kern local glue_code = nodecodes.glue +local whatsit_code = nodecodes.whatsit local texgetbox = tex.getbox @@ -30,21 +32,44 @@ local free_node = node.free local remove_node = node.remove local traverse_nodes = node.traverse -local function cleanup(head) -- rough +local removables = { + [whatsitcodes.open] = true, + [whatsitcodes.close] = true, + [whatsitcodes.write] = true, + [whatsitcodes.pdfdest] = true, + [whatsitcodes.pdfsavepos] = true, + [whatsitcodes.latelua] = true, +} + +local function cleanup_redundant(head) local start = head while start do local id = start.id - if id == disc_code or (id == glue_code and not start.writable) or (id == kern_code and start.kern == 0) or id == mark_code then - head, start, tmp = remove_node(head,start) - free_node(tmp) + if id == disc_code then + head, start = remove_node(head,start,true) + -- elseif id == glue_code then + -- if start.writable then + -- start = start.next + -- elseif some_complex_check_on_glue_spec then + -- head, start = remove_node(head,start,true) + -- else + -- start = start.next + -- end + elseif id == kern_code then + if start.kern == 0 then + head, start = remove_node(head,start,true) + else + start = start.next + end + elseif id == mark_code then + head, start = remove_node(head,start,true) elseif id == hlist_code or id == vlist_code then local sl = start.list if sl then - start.list = cleanup(sl) + start.list = cleanup_redundant(sl) start = start.next else - head, start, tmp = remove_node(head,start) - free_node(tmp) + head, start = remove_node(head,start,true) end else start = start.next @@ -53,21 +78,50 @@ local function cleanup(head) -- rough return head end -directives.register("backend.cleanup", function() - tasks.enableaction("shipouts","nodes.handlers.cleanuppage") -end) +local function cleanup_flushed(head) -- rough + local start = head + while start do + local id = start.id + if id == whatsit_code and removables[start.subtype] then + head, start = remove_node(head,start,true) + elseif id == hlist_code or id == vlist_code then + local sl = start.list + if sl then + start.list = cleanup_flushed(sl) + start = start.next + else + head, start = remove_node(head,start,true) + end + else + start = start.next + end + end + return head +end function handlers.cleanuppage(head) -- about 10% of the nodes make no sense for the backend - return cleanup(head), true + return cleanup_redundant(head), true end +function handlers.cleanupbox(head) + return cleanup_flushed(head), true +end + +directives.register("backend.cleanup", function() + tasks.enableaction("shipouts","nodes.handlers.cleanuppage") +end) + local actions = tasks.actions("shipouts") -- no extra arguments function handlers.finalize(head) -- problem, attr loaded before node, todo ... return actions(head) end +function commands.cleanupbox(n) + cleanup_flushed(texgetbox(n)) +end + -- handlers.finalize = actions -- interface |