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
10
11
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 = { }
28
29local sequencers = utilities.sequencers
30local compile = sequencers.compile
31local nodeprocessor = sequencers.nodeprocessor
32
33local newsequencer = sequencers.new
34
35local appendgroup = sequencers.appendgroup
36
37
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"
51end
52
53function tasks.new(specification)
54 local name = specification.name
55 local sequence = specification.sequence
56 if name and sequence then
57 local tasklist = newsequencer {
58 name = name
59
60 }
61 tasksdata[name] = {
62 name = name,
63 list = tasklist,
64 runner = false,
65 frozen = { },
66 processor = specification.processor or nodeprocessor,
67
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
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
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
215
216
217
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)
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
282
283
284
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",
331 "normalizers",
332 "finishers",
333 "after",
334 "wrapup",
335 },
336 templates = templates
337}
338
339tasks.new {
340 name = "everypar",
341 processor = nodeprocessor,
342 sequence = {
343 "before",
344 "normalizers",
345 "after",
346 },
347 templates = templates,
348}
349
350
351
352tasks.new {
353 name = "alignments",
354 processor = nodeprocessor,
355 sequence = {
356 "before",
357 "normalizers",
358 "after",
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
402
403tasks.new {
404 name = "finalizers",
405 sequence = {
406 "before",
407 "normalizers",
408 "fonts",
409 "lists",
410 "after",
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
455
456tasks.new {
457 name = "processors",
458 processor = nodeprocessor,
459 sequence = {
460 "before",
461 "normalizers",
462 "characters",
463 "words",
464 "fonts",
465 "lists",
466 "after",
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
510
511tasks.new {
512 name = "paragraphs",
513 processor = nodeprocessor,
514 sequence = {
515 "before",
516 "lists",
517 "after",
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
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615tasks.new {
616 name = "finalizers",
617 processor = nodeprocessor,
618 sequence = {
619 "before",
620 "normalizers",
621 "fonts",
622 "lists",
623 "after",
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",
671 "normalizers",
672 "after",
673 },
674 templates = {
675
676default = [[
677return function(head)
678 return head
679end
680]],
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
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",
736 "normalizers",
737 "after",
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",
786 "normalizers",
787 "after",
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
832
833tasks.new {
834 name = "contributers",
835 processor = nodeprocessor,
836 sequence = {
837 "before",
838 "normalizers",
839 "after",
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",
891 "normalizers",
892 "after",
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
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
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019tasks.new {
1020 name = "pagebuilders",
1021 processor = nodeprocessor,
1022 sequence = {
1023 "before",
1024 "normalizers",
1025 "after",
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
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138tasks.new {
1139 name = "localboxes",
1140 processor = nodeprocessor,
1141 sequence = {
1142 "before",
1143 "lists",
1144 "after",
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
1190
1191tasks.new {
1192 name = "hquality",
1193 processor = nodeprocessor,
1194 sequence = {
1195 "before",
1196 "system",
1197 "after",
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",
1247 "system",
1248 "after",
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 |