cld-callbacks.tex /size: 8959 b    last modification: 2021-10-28 13:50
1% language=us runpath=texruns:manuals/cld
2
3\startcomponent cld-callbacks
4
5\environment cld-environment
6
7\startchapter[title={Callbacks}]
8
9\startsection [title={Introduction}]
10
11\index {callbacks}
12
13The \LUATEX\ engine provides the usual basic \TEX\ functionality plus a bit more.
14It is a deliberate choice not to extend the core engine too much. Instead all
15relevant processes can be overloaded by new functionality written in \LUA. In
16\CONTEXT\ callbacks are wrapped in a protective layer: on the one hand there is
17extra functionality (usually interfaced through macros) and on the other hand
18users can pop in their own handlers using hooks. Of course a plugged in function
19has to do the right thing and not mess up the data structures. In this chapter
20the layer on top of callbacks is described.
21
22\stopsection
23
24\startsection [title={Actions}]
25
26\index {nodelists}
27
28Nearly all callbacks in \LUATEX\ are used in \CONTEXT. In the following list the
29callbacks tagged with \type {enabled} are used and frozen, the ones tagged \type
30{disabled} are blocked and never used, while the ones tagged \type {undefined}
31are yet unused.
32
33% \ctxlua{callbacks.table()} % \ctxlua{callbacks.report()}
34\ctxcommand{showcallbacks()}
35
36Eventually all callbacks will be used so don't rely on undefined callbacks not
37being protected. Some callbacks are only set when certain functionality is
38enabled.
39
40It may sound somewhat harsh but if users kick in their own code, we cannot
41guarantee \CONTEXT's behaviour any more and support becomes a pain. If you really
42need to use a callback yourself, you should use one of the hooks and make sure
43that you return the right values.
44
45All callbacks related to file handling, font definition and housekeeping are
46frozen and cannot be overloaded. A reason for this are that we need some kind of
47protection against misuse. Another reason is that we operate in a well defined
48environment, the so called \TEX\ directory structure, and we don't want to mess
49with that. And of course, the overloading permits \CONTEXT\ to provide extensions
50beyond regular engine functionality.
51
52So as a fact we only open up some of the node list related callbacks and these
53are grouped as follows:
54
55\starttabulate[|l|l|p|]
56\FL
57\NC \bf category \NC \bf callback \NC \bf usage \NC \NR
58\TL
59\NC \type{processors}   \NC \type{pre_linebreak_filter}  \NC called just before the paragraph is broken into lines \NC \NR
60\NC                     \NC \type{hpack_filter}          \NC called just before a horizontal box is constructed \NC \NR
61\NC \type{finalizers}   \NC \type{post_linebreak_filter} \NC called just after the paragraph has been broken into lines \NC \NR
62\NC \type{shipouts}     \NC \type{no callback yet}       \NC applied to the box (or xform) that is to be shipped out \NC \NR
63\NC \type{mvlbuilders}  \NC \type{buildpage_filter}      \NC called after some material has been added to the main vertical list \NC \NR
64\NC \type{vboxbuilders} \NC \type{vpack_filter}          \NC called when some material is added to a vertical box \NC \NR
65%NC \type{parbuilders}  \NC \type{linebreak_filter}      \NC called when a paragraph is to be broken into lines \NC \NR
66%NC \type{pagebuilders} \NC \type{pre_output_filter}     \NC called when a page it fed into the output routing \NC \NR
67\NC \type{math}         \NC \type{mlist_to_hlist}        \NC called just after the math list is created, before it is turned into an horizontal list \NC \NR
68\BL
69\stoptabulate
70
71Each category has several subcategories but for users only two make sense: \type
72{before} and \type {after}. Say that you want to hook some tracing into the \type
73{mvlbuilder}. This is how it's done:
74
75\starttyping
76function third.mymodule.myfunction(where)
77    nodes.show_simple_list(tex.lists.contrib_head)
78end
79
80nodes.tasks.appendaction("processors", "before", "third.mymodule.myfunction")
81\stoptyping
82
83As you can see, in this case the function gets no \type {head} passed (at least
84not currently). This example also assumes that you know how to access the right
85items. The arguments and return values are given below. \footnote {This interface
86might change a bit in future versions of \CONTEXT. Therefore we will not discuss
87the few more optional arguments that are possible.}
88
89\starttabulate[|l|l|p|]
90\FL
91\NC \bf category \NC \bf arguments \NC \bf return value \NC \NR
92\TL
93\NC \type{processors}   \NC \type{head, ...} \NC \type{head, done} \NC \NR
94\NC \type{finalizers}   \NC \type{head, ...} \NC \type{head, done} \NC \NR
95\NC \type{shipouts}     \NC \type{head}      \NC \type{head, done} \NC \NR
96\NC \type{mvlbuilders}  \NC                  \NC \type{done}       \NC \NR
97\NC \type{vboxbuilders} \NC \type{head, ...} \NC \type{head, done} \NC \NR
98\NC \type{parbuilders}  \NC \type{head, ...} \NC \type{head, done} \NC \NR
99\NC \type{pagebuilders} \NC \type{head, ...} \NC \type{head, done} \NC \NR
100\NC \type{math}         \NC \type{head, ...} \NC \type{head, done} \NC \NR
101\LL
102\stoptabulate
103
104\stopsection
105
106\startsection [title={Tasks}]
107
108\index {tasks}
109
110In the previous section we already saw that the actions are in fact tasks and
111that we can append (and therefore also prepend) to a list of tasks. The \type
112{before} and \type {after} task lists are valid hooks for users contrary to the
113other tasks that can make up an action. However, the task builder is generic
114enough for users to be used for individual tasks that are plugged into the user
115hooks.
116
117Of course at some point, too many nested tasks bring a performance penalty with
118them. At the end of a run \MKIV\ reports some statistics and timings and these
119can give you an idea how much time is spent in \LUA.
120
121The following tables list all the registered tasks for the processors actions:
122
123\ctxlua{nodes.tasks.table("processors")}
124
125Some of these do have subtasks and some of these even more, so you can imagine
126that quite some action is going on there.
127
128The finalizer tasks are:
129
130\ctxlua{nodes.tasks.table("finalizers")}
131
132Shipouts concern:
133
134\ctxlua{nodes.tasks.table("shipouts")}
135
136There are not that many mvlbuilder tasks currently:
137
138\ctxlua{nodes.tasks.table("mvlbuilders")}
139
140The vboxbuilder perform similar tasks:
141
142\ctxlua{nodes.tasks.table("vboxbuilders")}
143
144In the future we expect to have more parbuilder tasks. Here again there are
145subtasks that depend on the current typesetting environment, so this is the right
146spot for language specific treatments.
147
148\ctxlua{nodes.tasks.table("parbuilders")}
149
150The following actions are applied just before the list is passed on the the
151output routine. The return value is a vlist.
152
153\ctxlua{nodes.tasks.table("pagebuilders")}
154
155{\em Both the parbuilders and pagebuilder tasks are unofficial and not yet meant
156for users.}
157
158Finally, we have tasks related to the math list:
159
160\ctxlua{nodes.tasks.table("math")}
161
162As \MKIV\ is developed in sync with \LUATEX\ and code changes from experimental
163to more final and reverse, you should not be too surprised if the registered
164function names change.
165
166You can create your own task list with:
167
168\starttyping
169nodes.tasks.new("mytasks",{ "one", "two" })
170\stoptyping
171
172After that you can register functions. You can append as well as prepend them
173either or not at a specific position.
174
175\starttyping
176nodes.tasks.appendaction ("mytask","one","bla.alpha")
177nodes.tasks.appendaction ("mytask","one","bla.beta")
178
179nodes.tasks.prependaction("mytask","two","bla.gamma")
180nodes.tasks.prependaction("mytask","two","bla.delta")
181
182nodes.tasks.appendaction ("mytask","one","bla.whatever","bla.alpha")
183\stoptyping
184
185Functions can also be removed:
186
187\starttyping
188nodes.tasks.removeaction("mytask","one","bla.whatever")
189\stoptyping
190
191As removal is somewhat drastic, it is also possible to enable and disable
192functions. From the fact that with these two functions you don't specify a
193category (like \type {one} or \type {two}) you can conclude that the function
194names need to be unique within the task list or else all with the same name
195within this task will be disabled.
196
197\starttyping
198nodes.tasks.enableaction ("mytask","bla.whatever")
199nodes.tasks.disableaction("mytask","bla.whatever")
200\stoptyping
201
202The same can be done with a complete category:
203
204\starttyping
205nodes.tasks.enablegroup ("mytask","one")
206nodes.tasks.disablegroup("mytask","one")
207\stoptyping
208
209There is one function left:
210
211\starttyping
212nodes.tasks.actions("mytask",2)
213\stoptyping
214
215This function returns a function that when called will perform the tasks. In this
216case the function takes two extra arguments in addition to \type {head}.
217\footnote {Specifying this number permits for some optimization but is not really
218needed}
219
220Tasks themselves are implemented on top of sequences but we won't discuss them
221here.
222
223\stopsection
224
225\startsection [title={Paragraph and page builders}]
226
227Building paragraphs and pages is implemented differently and has no user hooks.
228There is a mechanism for plugins but the interface is quite experimental.
229
230\stopsection
231
232\startsection [title={Some examples}]
233
234{\em todo}
235
236\stopsection
237
238\stopchapter
239
240\stopcomponent
241