summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/cld/cld-callbacks.tex
blob: c449af864e78e0865cb5f6f699f5a1d36cbeb16f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
% language=uk

\startcomponent cld-callbacks

\environment cld-environment

\startchapter[title={Callbacks}]

\startsection [title={Introduction}]

\index {callbacks}

The \LUATEX\ engine provides the usual basic \TEX\ functionality plus a bit more.
It is a deliberate choice not to extend the core engine too much. Instead all
relevant processes can be overloaded by new functionality written in \LUA. In
\CONTEXT\ callbacks are wrapped in a protective layer: on the one hand there is
extra functionality (usually interfaced through macros) and on the other hand
users can pop in their own handlers using hooks. Of course a plugged in function
has to do the right thing and not mess up the data structures. In this chapter
the layer on top of callbacks is described.

\stopsection

\startsection [title={Actions}]

\index {nodelists}

Nearly all callbacks in \LUATEX\ are used in \CONTEXT. In the following list the
callbacks tagged with \type {enabled} are used and frozen, the ones tagged \type
{disabled} are blocked and never used, while the ones tagged \type {undefined}
are yet unused.

% \ctxlua{callbacks.table()} % \ctxlua{callbacks.report()}
\ctxcommand{showcallbacks()}

Eventually all callbacks will be used so don't rely on undefined callbacks not
being protected. Some callbacks are only set when certain functionality is
enabled.

It may sound somewhat harsh but if users kick in their own code, we cannot
guarantee \CONTEXT's behaviour any more and support becomes a pain. If you really
need to use a callback yourself, you should use one of the hooks and make sure
that you return the right values.

All callbacks related to file handling, font definition and housekeeping are
frozen and cannot be overloaded. A reason for this are that we need some kind of
protection against misuse. Another reason is that we operate in a well defined
environment, the so called \TEX\ directory structure, and we don't want to mess
with that. And of course, the overloading permits \CONTEXT\ to provide extensions
beyond regular engine functionality.

So as a fact we only open up some of the node list related callbacks and these
are grouped as follows:

\starttabulate[|l|l|p|]
\FL
\NC \bf category \NC \bf callback \NC \bf usage \NC \NR
\TL
\NC \type{processors}   \NC \type{pre_linebreak_filter}  \NC called just before the paragraph is broken into lines \NC \NR
\NC                     \NC \type{hpack_filter}          \NC called just before a horizontal box is constructed \NC \NR
\NC \type{finalizers}   \NC \type{post_linebreak_filter} \NC called just after the paragraph has been broken into lines \NC \NR
\NC \type{shipouts}     \NC \type{no callback yet}       \NC applied to the box (or xform) that is to be shipped out \NC \NR
\NC \type{mvlbuilders}  \NC \type{buildpage_filter}      \NC called after some material has been added to the main vertical list \NC \NR
\NC \type{vboxbuilders} \NC \type{vpack_filter}          \NC called when some material is added to a vertical box \NC \NR
%NC \type{parbuilders}  \NC \type{linebreak_filter}      \NC called when a paragraph is to be broken into lines \NC \NR
%NC \type{pagebuilders} \NC \type{pre_output_filter}     \NC called when a page it fed into the output routing \NC \NR
\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
\BL
\stoptabulate

Each category has several subcategories but for users only two make sense: \type
{before} and \type {after}. Say that you want to hook some tracing into the \type
{mvlbuilder}. This is how it's done:

\starttyping
function third.mymodule.myfunction(where)
    nodes.show_simple_list(tex.lists.contrib_head)
end

nodes.tasks.appendaction("processors", "before", "third.mymodule.myfunction")
\stoptyping

As you can see, in this case the function gets no \type {head} passed (at least
not currently). This example also assumes that you know how to access the right
items. The arguments and return values are given below. \footnote {This interface
might change a bit in future versions of \CONTEXT. Therefore we will not discuss
the few more optional arguments that are possible.}

\starttabulate[|l|l|p|]
\FL
\NC \bf category \NC \bf arguments \NC \bf return value \NC \NR
\TL
\NC \type{processors}   \NC \type{head, ...} \NC \type{head, done} \NC \NR
\NC \type{finalizers}   \NC \type{head, ...} \NC \type{head, done} \NC \NR
\NC \type{shipouts}     \NC \type{head}      \NC \type{head, done} \NC \NR
\NC \type{mvlbuilders}  \NC                  \NC \type{done}       \NC \NR
\NC \type{vboxbuilders} \NC \type{head, ...} \NC \type{head, done} \NC \NR
\NC \type{parbuilders}  \NC \type{head, ...} \NC \type{head, done} \NC \NR
\NC \type{pagebuilders} \NC \type{head, ...} \NC \type{head, done} \NC \NR
\NC \type{math}         \NC \type{head, ...} \NC \type{head, done} \NC \NR
\LL
\stoptabulate

\stopsection

\startsection [title={Tasks}]

\index {tasks}

In the previous section we already saw that the actions are in fact tasks and
that we can append (and therefore also prepend) to a list of tasks. The \type
{before} and \type {after} task lists are valid hooks for users contrary to the
other tasks that can make up an action. However, the task builder is generic
enough for users to be used for individual tasks that are plugged into the user
hooks.

Of course at some point, too many nested tasks bring a performance penalty with
them. At the end of a run \MKIV\ reports some statistics and timings and these
can give you an idea how much time is spent in \LUA.

The following tables list all the registered tasks for the processors actions:

\ctxlua{nodes.tasks.table("processors")}

Some of these do have subtasks and some of these even more, so you can imagine
that quite some action is going on there.

The finalizer tasks are:

\ctxlua{nodes.tasks.table("finalizers")}

Shipouts concern:

\ctxlua{nodes.tasks.table("shipouts")}

There are not that many mvlbuilder tasks currently:

\ctxlua{nodes.tasks.table("mvlbuilders")}

The vboxbuilder perform similar tasks:

\ctxlua{nodes.tasks.table("vboxbuilders")}

In the future we expect to have more parbuilder tasks. Here again there are
subtasks that depend on the current typesetting environment, so this is the right
spot for language specific treatments.

\ctxlua{nodes.tasks.table("parbuilders")}

The following actions are applied just before the list is passed on the the
output routine. The return value is a vlist.

\ctxlua{nodes.tasks.table("pagebuilders")}

{\em Both the parbuilders and pagebuilder tasks are unofficial and not yet meant
for users.}

Finally, we have tasks related to the math list:

\ctxlua{nodes.tasks.table("math")}

As \MKIV\ is developed in sync with \LUATEX\ and code changes from experimental
to more final and reverse, you should not be too surprised if the registered
function names change.

You can create your own task list with:

\starttyping
nodes.tasks.new("mytasks",{ "one", "two" })
\stoptyping

After that you can register functions. You can append as well as prepend them
either or not at a specific position.

\starttyping
nodes.tasks.appendaction ("mytask","one","bla.alpha")
nodes.tasks.appendaction ("mytask","one","bla.beta")

nodes.tasks.prependaction("mytask","two","bla.gamma")
nodes.tasks.prependaction("mytask","two","bla.delta")

nodes.tasks.appendaction ("mytask","one","bla.whatever","bla.alpha")
\stoptyping

Functions can also be removed:

\starttyping
nodes.tasks.removeaction("mytask","one","bla.whatever")
\stoptyping

As removal is somewhat drastic, it is also possible to enable and disable
functions. From the fact that with these two functions you don't specify a
category (like \type {one} or \type {two}) you can conclude that the function
names need to be unique within the task list or else all with the same name
within this task will be disabled.

\starttyping
nodes.tasks.enableaction ("mytask","bla.whatever")
nodes.tasks.disableaction("mytask","bla.whatever")
\stoptyping

The same can be done with a complete category:

\starttyping
nodes.tasks.enablegroup ("mytask","one")
nodes.tasks.disablegroup("mytask","one")
\stoptyping

There is one function left:

\starttyping
nodes.tasks.actions("mytask",2)
\stoptyping

This function returns a function that when called will perform the tasks. In this
case the function takes two extra arguments in addition to \type {head}.
\footnote {Specifying this number permits for some optimization but is not really
needed}

Tasks themselves are implemented on top of sequences but we won't discuss them
here.

\stopsection

\startsection [title={Paragraph and page builders}]

Building paragraphs and pages is implemented differently and has no user hooks.
There is a mechanism for plugins but the interface is quite experimental.

\stopsection

\startsection [title={Some examples}]

{\em todo}

\stopsection

\stopchapter

\stopcomponent