summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/hybrid/hybrid-callbacks.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context/sources/general/manuals/hybrid/hybrid-callbacks.tex')
-rw-r--r--doc/context/sources/general/manuals/hybrid/hybrid-callbacks.tex229
1 files changed, 229 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/hybrid/hybrid-callbacks.tex b/doc/context/sources/general/manuals/hybrid/hybrid-callbacks.tex
new file mode 100644
index 000000000..00b3c0f3f
--- /dev/null
+++ b/doc/context/sources/general/manuals/hybrid/hybrid-callbacks.tex
@@ -0,0 +1,229 @@
+% language=uk
+
+\startcomponent hybrid-callbacks
+
+\environment hybrid-environment
+
+\startchapter[title={Callbacks}]
+
+\startsection [title={Introduction}]
+
+Callbacks are the means to extend the basic \TEX\ engine's functionality in
+\LUATEX\ and \CONTEXT\ \MKIV\ uses them extensively. Although the interface is
+still in development we see users popping in their own functionality and although
+there is nothing wrong with that, it can open a can of worms.
+
+It is for this reason that from now on we protect the \MKIV\ callbacks from being
+overloaded. For those who still want to add their own code some hooks are
+provided. Here we will address some of these issues.
+
+\stopsection
+
+\startsection [title={Actions}]
+
+There are already quite some callbacks and we use most of them. 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.
+
+\ctxcommand{showcallbacks()}
+
+You can be rather sure that we will eventually use all callbacks one way or the
+other. Also, 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.
+
+The exact working of the callback handler is not something we need to bother
+users with so we stick to a simple description. The next list is not definitive
+and evolves. For instance we might at some point decide to add more granularity.
+
+We only open up some of the node list related callbacks. All callbacks related to
+file handling, font definition and housekeeping are frozen. Most if the
+mechanisms that use these callbacks have hooks anyway.
+
+Of course you can overload the built in functionality as this is currently not
+protected, but we might do that as well once \MKIV\ is stable enough. After all,
+at the time of this writing overloading can be handy when testing.
+
+This leaves the node list manipulators. The 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}]
+
+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. Of course this is a rough
+estimate only.
+
+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")}
+
+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
+
+\stopchapter
+
+\stopcomponent