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