summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/node-tsk.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkxl/node-tsk.lmt')
-rw-r--r--tex/context/base/mkxl/node-tsk.lmt796
1 files changed, 796 insertions, 0 deletions
diff --git a/tex/context/base/mkxl/node-tsk.lmt b/tex/context/base/mkxl/node-tsk.lmt
new file mode 100644
index 000000000..ca7c7fee4
--- /dev/null
+++ b/tex/context/base/mkxl/node-tsk.lmt
@@ -0,0 +1,796 @@
+if not modules then modules = { } end modules ['node-tsk'] = {
+ version = 1.001,
+ comment = "companion to node-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This might move to task-* and become less code as in sequencers
+-- we already have dirty flags as well. On the other hand, nodes are
+-- rather specialized and here we focus on node related tasks.
+
+local format = string.format
+
+local trace_tasks = false trackers.register("tasks.creation", function(v) trace_tasks = v end)
+
+local report_tasks = logs.reporter("tasks")
+
+local allocate = utilities.storage.allocate
+
+local context = context
+local nodes = nodes
+
+local tasks = nodes.tasks or { }
+nodes.tasks = tasks
+
+local tasksdata = { } -- no longer public
+
+local sequencers = utilities.sequencers
+local compile = sequencers.compile
+local nodeprocessor = sequencers.nodeprocessor
+
+local newsequencer = sequencers.new
+
+local appendgroup = sequencers.appendgroup
+----- prependgroup = sequencers.prependgroup
+----- replacegroup = sequencers.replacegroup
+local enablegroup = sequencers.enablegroup
+local disablegroup = sequencers.disablegroup
+
+local appendaction = sequencers.appendaction
+local prependaction = sequencers.prependaction
+local replaceaction = sequencers.replaceaction
+local enableaction = sequencers.enableaction
+local disableaction = sequencers.disableaction
+
+local frozengroups = "no"
+
+function tasks.freeze(kind)
+ frozengroups = kind or "tolerant" -- todo: hook into jobname
+end
+
+function tasks.new(specification) -- was: name,arguments,list
+ local name = specification.name
+ local sequence = specification.sequence
+ if name and sequence then
+ local tasklist = newsequencer {
+ name = name
+ -- we can move more to the sequencer now .. todo
+ }
+ tasksdata[name] = {
+ name = name,
+ list = tasklist,
+ runner = false,
+ frozen = { },
+ processor = specification.processor or nodeprocessor,
+ -- could be metatable but best freeze it
+ arguments = specification.arguments or 0,
+ templates = specification.templates,
+ }
+ for l=1,#sequence do
+ appendgroup(tasklist,sequence[l])
+ end
+ end
+end
+
+local function valid(name)
+ local data = tasksdata[name]
+ if not data then
+ report_tasks("unknown task %a",name)
+ else
+ return data
+ end
+end
+
+local function validgroup(name,group,what)
+ local data = tasksdata[name]
+ if not data then
+ report_tasks("unknown task %a",name)
+ else
+ local frozen = data.frozen[group]
+ if frozen then
+ if frozengroup == "no" then
+ -- default
+ elseif frozengroup == "strict" then
+ report_tasks("warning: group %a of task %a is frozen, %a applied but not supported",group,name,what)
+ return
+ else -- if frozengroup == "tolerant" then
+ report_tasks("warning: group %a of task %a is frozen, %a ignored",group,name,what)
+ end
+ end
+ return data
+ end
+end
+
+function tasks.freezegroup(name,group)
+ local data = valid(name)
+ if data then
+ data.frozen[group] = true
+ end
+end
+
+function tasks.restart(name)
+ local data = valid(name)
+ if data then
+ data.runner = false
+ end
+end
+
+function tasks.enableaction(name,action)
+ local data = valid(name)
+ if data then
+ enableaction(data.list,action)
+ data.runner = false
+ end
+end
+
+function tasks.disableaction(name,action)
+ local data = valid(name)
+ if data then
+ disableaction(data.list,action)
+ data.runner = false
+ end
+end
+
+function tasks.replaceaction(name,group,oldaction,newaction)
+ local data = valid(name)
+ if data then
+ replaceaction(data.list,group,oldaction,newaction)
+ data.runner = false
+ end
+end
+
+do
+
+ local enableaction = tasks.enableaction
+ local disableaction = tasks.disableaction
+
+ function tasks.setaction(name,action,value)
+ if value then
+ enableaction(name,action)
+ else
+ disableaction(name,action)
+ end
+ end
+
+end
+
+function tasks.enablegroup(name,group)
+ local data = validgroup(name,"enable group")
+ if data then
+ enablegroup(data.list,group)
+ data.runner = false
+ end
+end
+
+function tasks.disablegroup(name,group)
+ local data = validgroup(name,"disable group")
+ if data then
+ disablegroup(data.list,group)
+ data.runner = false
+ end
+end
+
+function tasks.appendaction(name,group,action,where,kind,state)
+ local data = validgroup(name,"append action")
+ if data then
+ local list = data.list
+ appendaction(list,group,action,where,kind)
+ if state == "disabled" or (state == "production" and environment.initex) then
+ disableaction(list,action)
+ end
+ data.runner = false
+ end
+end
+
+function tasks.prependaction(name,group,action,where,kind,state)
+ local data = validgroup(name,"prepend action")
+ if data then
+ local list = data.list
+ prependaction(list,group,action,where,kind)
+ if state == "disabled" or (state == "production" and environment.initex) then
+ disableaction(list,action)
+ end
+ data.runner = false
+ end
+end
+
+function tasks.removeaction(name,group,action)
+ local data = validgroup(name,"remove action")
+ if data then
+ removeaction(data.list,group,action)
+ data.runner = false
+ end
+end
+
+function tasks.showactions(name,group,action,where,kind)
+ local data = valid(name)
+ if data then
+ report_tasks("task %a, list:\n%s",name,nodeprocessor(data.list))
+ end
+end
+
+-- Optimizing for the number of arguments makes sense, but getting rid of
+-- the nested call (no problem but then we also need to register the
+-- callback with this mechanism so that it gets updated) does not save
+-- much time (24K calls on mk.tex).
+
+local created, total = 0, 0
+
+statistics.register("node list callback tasks", function()
+ if total > 0 then
+ return format("%s unique task lists, %s instances (re)created, %s calls",table.count(tasksdata),created,total)
+ else
+ return nil
+ end
+end)
+
+local function create(data,t)
+ created = created + 1
+ local runner = compile(data.list,data.processor,t)
+ if trace_tasks then
+ report_tasks("creating runner %a, %i actions enabled",t.name,data.list.steps or 0)
+ end
+ data.runner = runner
+ return runner
+end
+
+function tasks.actions(name)
+ local data = tasksdata[name]
+ if data then
+ local t = data.templates
+ if t then
+ t.name = data.name
+ return function(...)
+ total = total + 1
+ return (data.runner or create(data,t))(...)
+ end
+ end
+ end
+ return nil
+end
+
+function tasks.table(name) --maybe move this to task-deb.lua
+ local tsk = tasksdata[name]
+ local lst = tsk and tsk.list
+ local HL, NC, NR, bold, type = context.HL, context.NC, context.NR, context.bold, context.type
+ if lst then
+ local list, order = lst.list, lst.order
+ if list and order then
+ context.starttabulate { "|l|l|" }
+ NC() bold("category") NC() bold("function") NC() NR()
+ for i=1,#order do
+ HL()
+ local o = order[i]
+ local l = list[o]
+ if #l == 0 then
+ NC() type(o) NC() context("unset") NC() NR()
+ else
+ local done = false
+ for k, v in table.sortedhash(l) do
+ NC() if not done then type(o) done = true end NC() type(v) NC() NR()
+ end
+ end
+ end
+ context.stoptabulate()
+ end
+ end
+end
+
+-- -- shipouts everypar -- --
+
+-- the shipout handlers acts on boxes so we don't need to return something
+-- and also don't need to keep the state (done)
+
+local templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead))))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead))
+]],
+
+nonut = [[
+ %action%(nuthead)
+]],
+
+}
+
+tasks.new {
+ name = "shipouts",
+ processor = nodeprocessor,
+ sequence = {
+ "before", -- users
+ "normalizers", -- system
+ "finishers", -- system
+ "after", -- users
+ "wrapup", -- system
+ },
+ templates = templates
+}
+
+tasks.new {
+ name = "everypar",
+ processor = nodeprocessor,
+ sequence = {
+ "before", -- users
+ "normalizers", -- system
+ "after", -- users
+ },
+ templates = templates,
+}
+
+-- -- finalizers -- --
+
+tasks.new {
+ name = "finalizers",
+ sequence = {
+ "before", -- for users
+ "normalizers",
+ "fonts",
+ "lists",
+ "after", -- for users
+ },
+ processor = nodeprocessor,
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,groupcode)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode)
+]],
+
+ }
+}
+
+-- -- processors -- --
+
+tasks.new {
+ name = "processors",
+ processor = nodeprocessor,
+ sequence = {
+ "before", -- for users
+ "normalizers",
+ "characters",
+ "words",
+ "fonts",
+ "lists",
+ "after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,groupcode,size,packtype,direction,attributes)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,direction,attributes)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode,size,packtype,direction,attributes)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode,size,packtype,direction,attributes)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode,size,packtype,direction,attributes)
+]],
+
+ }
+}
+
+tasks.new {
+ name = "finalizers",
+ processor = nodeprocessor,
+ sequence = {
+ "before", -- for users
+ "normalizers",
+ "fonts",
+ "lists",
+ "after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead))))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead))
+]],
+
+nonut = [[
+ %action%(nuthead)
+]],
+
+ }
+}
+
+tasks.new {
+ name = "mvlbuilders",
+ processor = nodeprocessor,
+ sequence = {
+ "before", -- for users
+ "normalizers",
+ "after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,groupcode)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode)
+]],
+
+ }
+}
+
+tasks.new {
+ name = "vboxbuilders",
+ processor = nodeprocessor,
+ sequence = {
+ "before", -- for users
+ "normalizers",
+ "after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,groupcode,size,packtype,maxdepth,direction)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode,size,packtype,maxdepth,direction)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode,size,packtype,maxdepth,direction)
+]],
+
+ }
+
+}
+
+tasks.new {
+ name = "contributers",
+ processor = nodeprocessor,
+ sequence = {
+ "before", -- for users
+ "normalizers",
+ "after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+-- we operate exclusively on nuts
+
+return function(nuthead,groupcode,nutline)
+%actions%
+ return nuthead
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode,line)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode,nutline)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode,line)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode,nutline)
+]],
+
+ }
+}
+
+-- -- math -- --
+
+tasks.new {
+ name = "math",
+ processor = nodeprocessor,
+ sequence = {
+ "before",
+ "normalizers",
+ "builders",
+ "after",
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,style,penalties)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),style,penalties)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,style,penalties)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),style,penalties)
+]],
+
+nonut = [[
+ %action%(nuthead,style,penalties)
+]],
+
+ }
+}
+
+-- tasks.new {
+-- name = "parbuilders",
+-- arguments = 1,
+-- processor = nodeprocessor,
+-- sequence = {
+-- "before", -- for users
+-- "lists",
+-- "after", -- for users
+-- }
+-- }
+
+-- tasks.new {
+-- name = "pagebuilders",
+-- arguments = 5,
+-- processor = nodeprocessor,
+-- sequence = {
+-- "before", -- for users
+-- "lists",
+-- "after", -- for users
+-- }
+-- }
+
+-- for now quite useless (too fuzzy)
+--
+-- tasks.new {
+-- name = "listbuilders",
+-- processor = nodeprocessor,
+-- sequence = {
+-- "before", -- for users
+-- "normalizers",
+-- "after", -- for users
+-- },
+-- templates = {
+-- -- we don't need a default
+-- default = [[
+-- return function(box,location,prevdepth)
+-- return box, prevdepth
+-- end
+-- ]],
+-- process = [[
+-- %localize%
+-- return function(box,location,prevdepth,mirrored)
+-- %actions%
+-- return box, prevdepth
+-- end
+-- ]],
+-- step = [[
+-- box, prevdepth = %action%(box,location,prevdepth,mirrored)
+-- ]],
+-- },
+-- }
+
+-- -- math -- --
+
+-- not really a node processor
+
+-- tasks.new {
+-- name = "newpar",
+-- processor = nodeprocessor,
+-- sequence = {
+-- "before",
+-- "normalizers",
+-- "after",
+-- },
+-- templates = {
+--
+-- default = [[
+-- return function(mode,indent)
+-- return indent
+-- end
+-- ]],
+--
+-- process = [[
+-- %localize%
+--
+-- return function(mode,indent)
+--
+-- %actions%
+-- return indent
+-- end
+-- ]],
+--
+-- step = [[
+-- indent = %action%(mode,indent)
+-- ]],
+--
+-- }
+-- }