node-tsk.lmt /size: 24 Kb    last modification: 2024-01-16 09:03
1if not modules then modules = { } end modules ['node-tsk'] = {
2    version   = 1.001,
3    comment   = "companion to node-ini.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9-- This might move to task-* and become less code as in sequencers
10-- we already have dirty flags as well. On the other hand, nodes are
11-- rather specialized and here we focus on node related tasks.
12
13local format = string.format
14
15local trace_tasks = false  trackers.register("tasks.creation", function(v) trace_tasks = v end)
16
17local report_tasks  = logs.reporter("tasks")
18
19local allocate      = utilities.storage.allocate
20
21local context       = context
22local nodes         = nodes
23
24local tasks         = nodes.tasks or { }
25nodes.tasks         = tasks
26
27local tasksdata     = { } -- no longer public
28
29local sequencers    = utilities.sequencers
30local compile       = sequencers.compile
31local nodeprocessor = sequencers.nodeprocessor
32
33local newsequencer  = sequencers.new
34
35local appendgroup   = sequencers.appendgroup
36----- prependgroup  = sequencers.prependgroup
37----- replacegroup  = sequencers.replacegroup
38local enablegroup   = sequencers.enablegroup
39local disablegroup  = sequencers.disablegroup
40
41local appendaction  = sequencers.appendaction
42local prependaction = sequencers.prependaction
43local replaceaction = sequencers.replaceaction
44local enableaction  = sequencers.enableaction
45local disableaction = sequencers.disableaction
46
47local frozengroups  = "no"
48
49function tasks.freeze(kind)
50    frozengroups = kind or "tolerant" -- todo: hook into jobname
51end
52
53function tasks.new(specification) -- was: name,arguments,list
54    local name      = specification.name
55    local sequence  = specification.sequence
56    if name and sequence then
57        local tasklist = newsequencer {
58            name = name
59            -- we can move more to the sequencer now .. todo
60        }
61        tasksdata[name] = {
62            name      = name,
63            list      = tasklist,
64            runner    = false,
65            frozen    = { },
66            processor = specification.processor or nodeprocessor,
67            -- could be metatable but best freeze it
68            arguments = specification.arguments or 0,
69            templates = specification.templates,
70        }
71        for l=1,#sequence do
72            appendgroup(tasklist,sequence[l])
73        end
74    end
75end
76
77local function valid(name)
78    local data = tasksdata[name]
79    if not data then
80        report_tasks("unknown task %a",name)
81    else
82        return data
83    end
84end
85
86local function validgroup(name,group,what)
87    local data = tasksdata[name]
88    if not data then
89        report_tasks("unknown task %a",name)
90    else
91        local frozen = data.frozen[group]
92        if frozen then
93            if frozengroup == "no" then
94                -- default
95            elseif frozengroup == "strict" then
96                report_tasks("warning: group %a of task %a is frozen, %a applied but not supported",group,name,what)
97                return
98            else -- if frozengroup == "tolerant" then
99                report_tasks("warning: group %a of task %a is frozen, %a ignored",group,name,what)
100            end
101        end
102        return data
103    end
104end
105
106function tasks.freezegroup(name,group)
107    local data = valid(name)
108    if data then
109        data.frozen[group] = true
110    end
111end
112
113function tasks.restart(name)
114    local data = valid(name)
115    if data then
116        data.runner = false
117    end
118end
119
120function tasks.enableaction(name,action)
121    local data = valid(name)
122    if data then
123        enableaction(data.list,action)
124        data.runner = false
125    end
126end
127
128function tasks.disableaction(name,action)
129    local data = valid(name)
130    if data then
131        disableaction(data.list,action)
132        data.runner = false
133    end
134end
135
136function tasks.replaceaction(name,group,oldaction,newaction)
137    local data = valid(name)
138    if data then
139        replaceaction(data.list,group,oldaction,newaction)
140        data.runner = false
141    end
142end
143
144do
145
146    local enableaction  = tasks.enableaction
147    local disableaction = tasks.disableaction
148
149    function tasks.setaction(name,action,value)
150        if value then
151            enableaction(name,action)
152        else
153            disableaction(name,action)
154        end
155    end
156
157end
158
159function tasks.enablegroup(name,group)
160    local data = validgroup(name,"enable group")
161    if data then
162        enablegroup(data.list,group)
163        data.runner = false
164    end
165end
166
167function tasks.disablegroup(name,group)
168    local data = validgroup(name,"disable group")
169    if data then
170        disablegroup(data.list,group)
171        data.runner = false
172    end
173end
174
175function tasks.appendaction(name,group,action,where,kind,state)
176    local data = validgroup(name,"append action")
177    if data then
178        local list = data.list
179        appendaction(list,group,action,where,kind)
180        if state == "disabled" or (state == "production" and environment.initex) then
181            disableaction(list,action)
182        end
183        data.runner = false
184    end
185end
186
187function tasks.prependaction(name,group,action,where,kind,state)
188    local data = validgroup(name,"prepend action")
189    if data then
190        local list = data.list
191        prependaction(list,group,action,where,kind)
192        if state == "disabled" or (state == "production" and environment.initex) then
193            disableaction(list,action)
194        end
195        data.runner = false
196    end
197end
198
199function tasks.removeaction(name,group,action)
200    local data = validgroup(name,"remove action")
201    if data then
202        removeaction(data.list,group,action)
203        data.runner = false
204    end
205end
206
207function tasks.showactions(name,group,action,where,kind)
208    local data = valid(name)
209    if data then
210        report_tasks("task %a, list:\n%s",name,nodeprocessor(data.list))
211    end
212end
213
214-- Optimizing for the number of arguments makes sense, but getting rid of
215-- the nested call (no problem but then we also need to register the
216-- callback with this mechanism so that it gets updated) does not save
217-- much time (24K calls on mk.tex).
218
219local created, total = 0, 0
220
221statistics.register("node list callback tasks", function()
222    if total > 0 then
223        return format("%s unique task lists, %s instances (re)created, %s calls",table.count(tasksdata),created,total)
224    else
225        return nil
226    end
227end)
228
229local function create(data,t)
230    created = created + 1
231    local runner = compile(data.list,data.processor,t)
232    if trace_tasks then
233        report_tasks("creating runner %a, %i actions enabled",t.name,data.list.steps or 0)
234    end
235    data.runner = runner
236    return runner
237end
238
239function tasks.actions(name)
240    local data = tasksdata[name]
241    if data then
242        local t = data.templates
243        if t then
244            t.name = data.name
245            return function(...)
246                total = total + 1
247                return (data.runner or create(data,t))(...)
248            end
249        end
250    end
251    return nil
252end
253
254function tasks.table(name) --maybe move this to task-deb.lua
255    local tsk = tasksdata[name]
256    local lst = tsk and tsk.list
257    local HL, NC, NR, bold, type = context.HL, context.NC, context.NR, context.bold, context.type
258    if lst then
259        local list, order = lst.list, lst.order
260        if list and order then
261            context.starttabulate { "|l|l|" }
262            NC() bold("category") NC() bold("function") NC() NR()
263            for i=1,#order do
264                HL()
265                local o = order[i]
266                local l = list[o]
267                if #l == 0 then
268                    NC() type(o) NC() context("unset") NC() NR()
269                else
270                    local done = false
271                    for k, v in table.sortedhash(l) do
272                        NC() if not done then type(o) done = true end NC() type(v) NC() NR()
273                    end
274                end
275            end
276            context.stoptabulate()
277        end
278    end
279end
280
281-- -- shipouts everypar -- --
282
283-- the shipout handlers acts on boxes so we don't need to return something
284-- and also don't need to keep the state (done)
285
286local templates = {
287
288default = [[
289return function(head)
290    return head
291end
292]],
293
294process = [[
295local tonut  = nodes.tonut
296local tonode = nodes.nuts.tonode
297
298%localize%
299
300return function(head)
301    local nuthead = tonut(head)
302
303%actions%
304    return tonode(nuthead)
305end
306]],
307
308step = [[
309    nuthead = tonut((%action%(tonode(nuthead))))
310]],
311
312nut  = [[
313    nuthead = %action%(nuthead)
314]],
315
316nohead = [[
317    %action%(tonode(nuthead))
318]],
319
320nonut = [[
321    %action%(nuthead)
322]],
323
324}
325
326tasks.new {
327    name      = "shipouts",
328    processor = nodeprocessor,
329    sequence  = {
330        "before",      -- users
331        "normalizers", -- system
332        "finishers",   -- system
333        "after",       -- users
334        "wrapup",      -- system
335    },
336    templates = templates
337}
338
339tasks.new {
340    name      = "everypar",
341    processor = nodeprocessor,
342    sequence  = {
343        "before",      -- users
344        "normalizers", -- system
345        "after",       -- users
346    },
347    templates = templates,
348}
349
350-- -- alignment -- -- gets temp node ! (currently as that might change)
351
352tasks.new {
353    name      = "alignments",
354    processor = nodeprocessor,
355    sequence  = {
356        "before",      -- users
357        "normalizers", -- system
358        "after",       -- users
359    },
360    templates = {
361
362default = [[
363return function(head)
364end
365]],
366
367process = [[
368local tonut  = nodes.tonut
369local tonode = nodes.nuts.tonode
370
371%localize%
372
373return function(head,where,callback,attr,preamble)
374    local nuthead     = tonut(head)
375    local nutattr     = tonut(attr)
376    local nutpreamble = tonut(preamble)
377
378%actions%
379end
380]],
381
382step = [[
383    %action%(head,where,callback,attr,preamble)
384]],
385
386nut  = [[
387    %action%(nuthead,where,callback,nutattr,nutpreamble)
388]],
389
390nohead = [[
391    %action%(head,where,callback,attr,preamble)
392]],
393
394nonut = [[
395    %action%(nuthead,where,callback,nutattr,nutpreamble)
396]],
397
398    }
399}
400
401-- -- finalizers -- --
402
403tasks.new {
404    name      = "finalizers",
405    sequence  = {
406        "before",      -- for users
407        "normalizers",
408        "fonts",
409        "lists",
410        "after",       -- for users
411    },
412    processor = nodeprocessor,
413    templates = {
414
415default = [[
416return function(head)
417    return head
418end
419]],
420
421process = [[
422local tonut  = nodes.tonut
423local tonode = nodes.nuts.tonode
424
425%localize%
426
427return function(head,groupcode)
428    local nuthead = tonut(head)
429
430%actions%
431    return tonode(nuthead)
432end
433]],
434
435step = [[
436    nuthead = tonut((%action%(tonode(nuthead),groupcode)))
437]],
438
439nut  = [[
440    nuthead = %action%(nuthead,groupcode)
441]],
442
443nohead = [[
444    %action%(tonode(nuthead),groupcode)
445]],
446
447nonut = [[
448    %action%(nuthead,groupcode)
449]],
450
451    }
452}
453
454-- -- processors -- --
455
456tasks.new {
457    name      = "processors",
458    processor = nodeprocessor,
459    sequence  = {
460        "before",      -- for users
461        "normalizers",
462        "characters",
463        "words",
464        "fonts",
465        "lists",
466        "after",       -- for users
467    },
468    templates = {
469
470default = [[
471return function(head)
472    return head
473end
474]],
475
476process = [[
477local tonut  = nodes.tonut
478local tonode = nodes.nuts.tonode
479
480%localize%
481
482return function(head,groupcode,direction)
483    local nuthead = tonut(head)
484
485%actions%
486    return tonode(nuthead)
487end
488]],
489
490step = [[
491    nuthead = tonut((%action%(tonode(nuthead),groupcode,direction)))
492]],
493
494nut  = [[
495    nuthead = %action%(nuthead,groupcode,direction)
496]],
497
498nohead = [[
499    %action%(tonode(nuthead),groupcode,direction)
500]],
501
502nonut = [[
503    %action%(nuthead,groupcode,direction)
504]],
505
506    }
507}
508
509-- -- paragraphs -- --
510
511tasks.new {
512    name      = "paragraphs",
513    processor = nodeprocessor,
514    sequence  = {
515        "before",      -- for users
516        "lists",
517        "after",       -- for users
518    },
519    templates = {
520
521default = [[
522return function(head)
523    return head
524end
525]],
526
527process = [[
528local tonut  = nodes.tonut
529local tonode = nodes.nuts.tonode
530
531%localize%
532
533return function(head,groupcode)
534    local nuthead = tonut(head)
535
536%actions%
537    return tonode(nuthead)
538end
539]],
540
541step = [[
542    nuthead = tonut((%action%(tonode(nuthead),groupcode)))
543]],
544
545nut  = [[
546    nuthead = %action%(nuthead,groupcode)
547]],
548
549nohead = [[
550    %action%(tonode(nuthead),groupcode)
551]],
552
553nonut = [[
554    %action%(nuthead,groupcode)
555]],
556
557    }
558}
559
560-- -- hpackers -- --
561
562-- tasks.new {
563--     name      = "processors",
564--     processor = nodeprocessor,
565--     sequence  = {
566--         "before",      -- for users
567--         "normalizers",
568--         "characters",
569--         "words",
570--         "fonts",
571--         "lists",
572--         "after",       -- for users
573--     },
574--     templates = {
575--
576-- default = [[
577-- return function(head)
578--     return head
579-- end
580-- ]],
581--
582-- process = [[
583-- local tonut  = nodes.tonut
584-- local tonode = nodes.nuts.tonode
585--
586-- %localize%
587--
588-- return function(head,groupcode,size,packtype,direction,attributes)
589--     local nuthead = tonut(head)
590--
591-- %actions%
592--     return tonode(nuthead)
593-- end
594-- ]],
595--
596-- step = [[
597--     nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,direction,attributes)))
598-- ]],
599--
600-- nut  = [[
601--     nuthead = %action%(nuthead,groupcode,size,packtype,direction,attributes)
602-- ]],
603--
604-- nohead = [[
605--     %action%(tonode(nuthead),groupcode,size,packtype,direction,attributes)
606-- ]],
607--
608-- nonut = [[
609--     %action%(nuthead,groupcode,size,packtype,direction,attributes)
610-- ]],
611--
612--     }
613-- }
614
615tasks.new {
616    name      = "finalizers",
617    processor = nodeprocessor,
618    sequence  = {
619        "before",      -- for users
620        "normalizers",
621        "fonts",
622        "lists",
623        "after",       -- for users
624    },
625    templates = {
626
627default = [[
628return function(head)
629    return head
630end
631]],
632
633process = [[
634local tonut  = nodes.tonut
635local tonode = nodes.nuts.tonode
636
637%localize%
638
639return function(head)
640    local nuthead = tonut(head)
641
642%actions%
643    return tonode(nuthead)
644end
645]],
646
647step = [[
648    nuthead = tonut((%action%(tonode(nuthead))))
649]],
650
651nut  = [[
652    nuthead = %action%(nuthead)
653]],
654
655nohead = [[
656    %action%(tonode(nuthead))
657]],
658
659nonut = [[
660    %action%(nuthead)
661]],
662
663    }
664}
665
666tasks.new {
667    name      = "mvlbuilders",
668    processor = nodeprocessor,
669    sequence  = {
670        "before",      -- for users
671        "normalizers",
672        "after",       -- for users
673    },
674    templates = {
675
676default = [[
677return function(head)
678    return head
679end
680]],
681
682-- process = [[
683-- local tonut  = nodes.tonut
684-- local tonode = nodes.nuts.tonode
685--
686-- %localize%
687--
688-- return function(head,groupcode)
689--     local nuthead = tonut(head)
690--
691-- return function(nuthead,groupcode)
692--
693-- %actions%
694--     return tonode(nuthead)
695-- end
696-- ]],
697
698process = [[
699local tonut  = nodes.tonut
700local tonode = nodes.nuts.tonode
701
702%localize%
703
704return function(nuthead,groupcode)
705
706%actions%
707    return nuthead
708end
709]],
710
711step = [[
712    nuthead = tonut((%action%(tonode(nuthead),groupcode)))
713]],
714
715nut  = [[
716    nuthead = %action%(nuthead,groupcode)
717]],
718
719nohead = [[
720    %action%(tonode(nuthead),groupcode)
721]],
722
723nonut = [[
724    %action%(nuthead,groupcode)
725]],
726
727    }
728
729}
730
731tasks.new {
732    name      = "vboxbuilders",
733    processor = nodeprocessor,
734    sequence  = {
735        "before",      -- for users
736        "normalizers",
737        "after",       -- for users
738    },
739    templates = {
740
741default = [[
742return function(head)
743    return head
744end
745]],
746
747process = [[
748local tonut  = nodes.tonut
749local tonode = nodes.nuts.tonode
750
751%localize%
752
753return function(head,groupcode,size,packtype,maxdepth,direction)
754    local nuthead = tonut(head)
755
756%actions%
757    return tonode(nuthead)
758end
759]],
760
761step = [[
762    nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction)))
763]],
764
765nut  = [[
766    nuthead = %action%(nuthead,groupcode,size,packtype,maxdepth,direction)
767]],
768
769nohead = [[
770    %action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction)
771]],
772
773nonut = [[
774    %action%(nuthead,groupcode,size,packtype,maxdepth,direction)
775]],
776
777    }
778
779}
780
781tasks.new {
782    name      = "vboxhandlers",
783    processor = nodeprocessor,
784    sequence  = {
785        "before",      -- for users
786        "normalizers",
787        "after",       -- for users
788    },
789    templates = {
790
791default = [[
792return function(head)
793    return head
794end
795]],
796
797process = [[
798local tonut  = nodes.tonut
799local tonode = nodes.nuts.tonode
800
801%localize%
802
803return function(head,groupcode)
804    local nuthead = tonut(head)
805
806%actions%
807    return tonode(nuthead)
808end
809]],
810
811step = [[
812    nuthead = tonut((%action%(tonode(nuthead),groupcode)))
813]],
814
815nut  = [[
816    nuthead = %action%(nuthead,groupcode)
817]],
818
819nohead = [[
820    %action%(tonode(nuthead),groupcode)
821]],
822
823nonut = [[
824    %action%(nuthead,groupcode)
825]],
826
827    }
828
829}
830
831-- these operate on the content on a line, so no injections
832
833tasks.new {
834    name      = "contributers",
835    processor = nodeprocessor,
836    sequence  = {
837        "before",      -- for users
838        "normalizers",
839        "after",       -- for users
840    },
841    templates = {
842
843default = [[
844return function(head)
845    return head
846end
847]],
848
849process = [[
850local tonut  = nodes.tonut
851local tonode = nodes.nuts.tonode
852
853%localize%
854
855-- we operate exclusively on nuts (no index yet)
856
857return function(head,where,tail)
858    local nuthead = tonut(head)
859    local nuttail = tonut(tail)
860
861%actions%
862    return tonode(nuthead)
863end
864]],
865
866step = [[
867    nuthead = tonut((%action%(tonode(nuthead),where,tonode(nuttail))))
868]],
869
870nut  = [[
871    nuthead = %action%(nuthead,where,nuttail)
872]],
873
874nohead = [[
875    %action%(tonode(nuthead),where,tonode(nuttail))
876]],
877
878nonut = [[
879    %action%(nuthead,where,nuttail)
880]],
881
882    }
883
884}
885
886    tasks.new {
887        name      = "adjusters",
888        processor = nodeprocessor,
889        sequence  = {
890            "before",      -- for users
891            "normalizers",
892            "after",       -- for users
893        },
894        templates = {
895
896default = [[
897return function(head)
898    return head
899end
900]],
901
902process = [[
903local tonut    = nodes.tonut
904local tonode   = nodes.nuts.tonode
905local nodetail = nodes.nuts.tail
906
907%localize%
908
909-- we operate exclusively on nuts
910
911return function(head,where,tail,index)
912    local nuthead = tonut(head)
913    local nuttail = tonut(tail)
914
915%actions%
916    return tonode(nuthead)
917end
918]],
919
920step = [[
921    nuthead = tonut((%action%(tonode(nuthead),where,tonode(nuttail),index)))
922    nuttail = nodetail(nuthead)
923]],
924
925nut  = [[
926    nuthead = %action%(nuthead,where,nuttail,index)
927    nuttail = nodetail(nuthead)
928]],
929
930nohead = [[
931    %action%(tonode(nuthead),where,tonode(nuttail),index)
932    nuttail = nodetail(nuthead)
933]],
934
935nonut = [[
936    %action%(nuthead,where,nuttail,index)
937    nuttail = nodetail(nuthead)
938]],
939
940    }
941
942}
943
944-- -- math -- --
945
946tasks.new {
947    name      = "math",
948    processor = nodeprocessor,
949    sequence  = {
950        "before",
951        "normalizers",
952        "builders",
953        "finalizers",
954        "after",
955    },
956    templates = {
957
958default = [[
959return function(head)
960    return head
961end
962]],
963
964process = [[
965local tonut  = nodes.tonut
966local tonode = nodes.nuts.tonode
967
968%localize%
969
970return function(head,style,penalties,beginclass,endclass,level)
971    local nuthead = tonut(head)
972
973%actions%
974    return tonode(nuthead)
975end
976]],
977
978step = [[
979    nuthead = tonut((%action%(tonode(nuthead),style,penalties,beginclass,endclass,level)))
980]],
981
982nut  = [[
983    nuthead = %action%(nuthead,style,penalties,beginclass,endclass,level)
984]],
985
986nohead = [[
987    %action%(tonode(nuthead),style,penalties,beginclass,endclass,level)
988]],
989
990nonut = [[
991    %action%(nuthead,style,penalties,beginclass,endclass,level)
992]],
993
994    }
995}
996
997-- tasks.new {
998--     name      = "parbuilders",
999--     arguments = 1,
1000--     processor = nodeprocessor,
1001--     sequence  = {
1002--         "before",      -- for users
1003--         "lists",
1004--         "after",       -- for users
1005--     }
1006-- }
1007
1008-- tasks.new {
1009--     name      = "pagebuilders",
1010--     arguments = 5,
1011--     processor = nodeprocessor,
1012--     sequence  = {
1013--         "before",      -- for users
1014--         "lists",
1015--         "after",       -- for users
1016--     }
1017-- }
1018
1019tasks.new {
1020    name      = "pagebuilders",
1021    processor = nodeprocessor,
1022    sequence  = {
1023        "before",      -- for users
1024        "normalizers",
1025        "after",       -- for users
1026    },
1027    templates = {
1028
1029default = [[
1030return function(head)
1031    return head
1032end
1033]],
1034
1035process = [[
1036local tonut  = nodes.tonut
1037local tonode = nodes.nuts.tonode
1038
1039%localize%
1040
1041return function(head,groupcode,size,packtype,maxdepth,direction)
1042    local nuthead = tonut(head)
1043
1044%actions%
1045    return tonode(nuthead)
1046end
1047]],
1048
1049step = [[
1050    nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction)))
1051]],
1052
1053nut  = [[
1054    nuthead = %action%(nuthead,groupcode,size,packtype,maxdepth,direction)
1055]],
1056
1057nohead = [[
1058    %action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction)
1059]],
1060
1061nonut = [[
1062    %action%(nuthead,groupcode,size,packtype,maxdepth,direction)
1063]],
1064
1065    }
1066
1067}
1068
1069-- for now quite useless (too fuzzy)
1070--
1071-- tasks.new {
1072--     name            = "listbuilders",
1073--     processor       = nodeprocessor,
1074--     sequence        = {
1075--         "before",      -- for users
1076--         "normalizers",
1077--         "after",       -- for users
1078--     },
1079--     templates       = {
1080-- -- we don't need a default
1081--         default = [[
1082-- return function(box,location,prevdepth)
1083--     return box, prevdepth
1084-- end
1085--         ]],
1086--         process = [[
1087-- %localize%
1088-- return function(box,location,prevdepth,mirrored)
1089--     %actions%
1090--     return box, prevdepth
1091-- end
1092--         ]],
1093--         step = [[
1094-- box, prevdepth = %action%(box,location,prevdepth,mirrored)
1095--         ]],
1096--     },
1097-- }
1098
1099-- -- math -- --
1100
1101-- not really a node processor
1102
1103-- tasks.new {
1104--     name      = "newpar",
1105--     processor = nodeprocessor,
1106--     sequence  = {
1107--         "before",
1108--         "normalizers",
1109--         "after",
1110--     },
1111--     templates = {
1112--
1113-- default = [[
1114-- return function(mode,indent)
1115--     return indent
1116-- end
1117-- ]],
1118--
1119-- process = [[
1120-- %localize%
1121--
1122-- return function(mode,indent)
1123--
1124-- %actions%
1125--     return indent
1126-- end
1127-- ]],
1128--
1129-- step = [[
1130--     indent = %action%(mode,indent)
1131-- ]],
1132--
1133--     }
1134-- }
1135
1136-- -- localboxes -- --
1137
1138tasks.new {
1139    name      = "localboxes",
1140    processor = nodeprocessor,
1141    sequence  = {
1142        "before",      -- for users
1143        "lists",
1144        "after",       -- for users
1145    },
1146    templates = {
1147
1148default = [[
1149return function(head)
1150end
1151]],
1152
1153process = [[
1154local tonut  = nodes.tonut
1155local tonode = nodes.nuts.tonode
1156
1157%localize%
1158
1159-- line,leftbox,rightbox,middlebox,linenumber,leftskip,rightskip,lefthang,righthang,indent,parinitleftskip,parinitrightskip,parfillleftskip,parfillrightskip,overshoot
1160
1161return function(line,leftbox,rightbox,middlebox,...)
1162    nutline      = tonut(line)
1163    nutleftbox   = leftbox  and tonut(leftbox)
1164    nutrightbox  = rightbox and tonut(rightbox)
1165    nutmiddlebox = middlebox and tonut(middlebox)
1166%actions%
1167end
1168]],
1169
1170step = [[
1171    tonut((%action%(line,leftbox,rightbox,middlebox,...)))
1172]],
1173
1174nut  = [[
1175    %action%(nutline,nutleftbox,nutrightbox,nutmiddlebox,...)
1176]],
1177
1178nohead = [[
1179    %action%(line,leftbox,rightbox,middlebox,...)
1180]],
1181
1182nonut = [[
1183    %action%(nutline,nutleftbox,nutrightbox,nutmiddlebox,...)
1184]],
1185
1186    }
1187}
1188
1189-- -- quality -- --
1190
1191tasks.new {
1192    name      = "hquality",
1193    processor = nodeprocessor,
1194    sequence  = {
1195        "before",      -- for users
1196        "system",
1197        "after",       -- for users
1198    },
1199    templates = {
1200
1201default = [[
1202return function(how,detail,nod,first,last,filename)
1203    -- nil
1204end
1205]],
1206
1207process = [[
1208local tonut  = nodes.tonut
1209local tonode = nodes.nuts.tonode
1210
1211%localize%
1212
1213return function(how,detail,nod,first,last,filename)
1214    local nut = tonut(nod)
1215    local rul = nil
1216
1217%actions%
1218
1219    return rul and tonode(rul)
1220end
1221]],
1222
1223step = [[
1224    rul = tonut((%action%(how,detail,nod,first,last,filename,rul and tonode(rul))))
1225]],
1226
1227nut  = [[
1228    rul = %action%(how,detail,nut,first,last,filename,rul)
1229]],
1230
1231nohead = [[
1232    %action%(how,detail,nod,first,last,filename,rul and tonode(rul))
1233]],
1234
1235nonut = [[
1236    %action%(how,detail,nut,first,last,filename,rul)
1237]],
1238
1239    }
1240}
1241
1242tasks.new {
1243    name      = "vquality",
1244    processor = nodeprocessor,
1245    sequence  = {
1246        "before",      -- for users
1247        "system",
1248        "after",       -- for users
1249    },
1250    templates = {
1251
1252default = [[
1253return function(how,detail,nod,first,last,filename)
1254    -- nil
1255end
1256]],
1257
1258process = [[
1259local tonut  = nodes.tonut
1260local tonode = nodes.nuts.tonode
1261
1262%localize%
1263
1264return function(how,detail,nod,first,last,filename)
1265    local nut = tonut(nod)
1266    local rul = nil
1267
1268%actions%
1269    return rul and tonode(rul)
1270end
1271]],
1272
1273step = [[
1274    rul = tonut((%action%(how,detail,nod,first,last,filename,tonode(rul))))
1275]],
1276
1277nut  = [[
1278    rul = %action%(how,detail,nut,first,last,filename,rul)
1279]],
1280
1281nohead = [[
1282    %action%(how,detail,nod,first,last,filename,rul and tonode(rul))
1283]],
1284
1285nonut = [[
1286    %action%(how,detail,nut,first,last,filename,rul)
1287]],
1288
1289    }
1290}
1291