Difference between revisions of "Callbacks"
(Corrected description of mlist_to_hlist.) |
(Link to the post_linebreak_filter page.) |
||
Line 173: | Line 173: | ||
|[[linebreak_filter]] ||head, is_display ||newhead ||The paragraph builder. It receives what the previous callback has returned and is in charge of making a paragraph out of it; it must return what it has built. An associated function is <tt>tex.linebreak()</tt>. | |[[linebreak_filter]] ||head, is_display ||newhead ||The paragraph builder. It receives what the previous callback has returned and is in charge of making a paragraph out of it; it must return what it has built. An associated function is <tt>tex.linebreak()</tt>. | ||
|- | |- | ||
− | |[[ | + | |[[post_linebreak_filter]] ||head, groupcode, ||boolean or newhead ||Receives what has been returned by <tt>linebreak_filter</tt> and must return something similar. |
|- | |- | ||
|[[hpack_filter]] ||head, context, size, packtype[, dir] ||boolean or newhead ||Called when TeX is going to build an <tt>\hbox</tt>. | |[[hpack_filter]] ||head, context, size, packtype[, dir] ||boolean or newhead ||Called when TeX is going to build an <tt>\hbox</tt>. |
Revision as of 11:28, 11 May 2011
Callbacks allow the user to interact with TeX's internal operations; those can be enhanced by additional ones, but also replaced altogether. All callbacks are written in Lua.
Since functions registered in callbacks occur in a sequence of actions that makes up TeX's processing, many of them will receive arguments (and thus should be defined to handle them) and, most importantly, many are supposed to return values. What arguments are passed, if any, and what should be return, vary from callback to callback.
Contents
Registering a callback
To install a function in a callback one must use the callback.register() function, whose syntax is:
callback.register(callback_name, function)
where callback_name is a string representing a predefined callback name (see below), and function is either a function variable or an anonymous function. The former is just the name of a function previously defined, for instance:
local my_function = function (an_arg) do_this_or_that(an_arg) end callback.register("some_callback", my_function)
An anonymous function is a function definition that is not assigned to a variable, e.g.:
callback.register("some_callback", function (an_arg) do_this_or_that(an_arg) end)
Even in the case of a function variable, what LuaTeX registers is the function itself, and any further assignment to the variable has no effect on the callback.
If registering is successful, callback.register() returns a number, which is the internal representation of the callback; if registering fails (for instance because a callback doesn't exist, or what is registered isn't a function), the function returns nil and a string representing an error message.
Besides functions, callback.register() can take nil or false. The first value clears the callback, and returns to the default behavior (i.e. either nothing or TeX's default processing); the second value prevents anything from happening at this point, even TeX's default operations, and should be used with great care (the benefits are minor speed gain).
Several functions in a callback
Each call to callback.register() erases any function previously registered. I.e. after
callback.register("some_callback", function_one) callback.register("some_callback", function_two)
only function_two is registered in some_callback. Hence, if one wants several successive functions to occur in a callback, callback.register() is clearly insufficient. Instead, one must register a metafunction which calls the functions one after the other. This is taken care of in ConTeXt, and there exists luatexbase-mcb for plain TeX and LaTeX, but here's how to do it oneself. We'll take the process_input_buffer callback has an example; it is called whenever TeX reads an input line, it receives a string (the line) and should return one. A rough approach would be:
local function_table = { } local function metafunction (str) for _, fct in ipairs(function_table) do str = fct(str) end return str end function add_function (fct) table.insert(function_table, fct) end callback.register("process_input_buffer", metafunction)
Then one can call add_function(my_function) to add my_function to the list of functions registered in process_input_buffer, and metafunction will pass the callback's argument (an input line) to the first function, set that argument to what the function returns, then repeat the process for all functions and finally return the resulting string.
If one also wants to be able to remove functions (and not the entire metafunction), a subtler approach is required, where names are associated with functions and can be used as handles.
Information about callbacks
LuaTeX has two functions to get some information about callbacks. The first is callback.list(), called without arguments and returning a table with the callback names as keys and booleans as values: if the value is true, it means that something is registered in the callback, or that it is set to false (see above). The other function is callback.find(), called with a callback name. If a function is registered, it is returned; if the callback is set to false, a boolean with that value is returned; finally, if nothing is registered, nil is returned (note that to distinguish between a boolean set to false and nil, you must use type()).
List of callbacks
For suggestions on how to document callbacks, see the discussion page.
File discovery callbacks
These are called whenever an input file is needed. Each receives the asked_name, a string representing what file name was called by the user (for instance, my_file.tex in \input my_file.tex) and should return the name of a file to be read (or written to). The id_number in the first two callbacks is the stream's number plus one, because 0 denotes log and \input files.
Name | Argument(s) | Return value(s) | Short description |
---|---|---|---|
find_read_file | id_number, asked_name | actual_name | File called with \read or \input |
find_write_file | id_number, asked_name | actual_name | log file or file called with \write |
find_font_file | asked_name | actual_name | |
find_output_file | asked_name | actual_name | |
find_format_file | asked_name | actual_name | |
find_vf_file | asked_name | actual_name | |
find_map_file | asked_name | actual_name | |
find_enc_file | asked_name | actual_name | |
find_sfd_file | asked_name | actual_name | |
find_pk_file | asked_name | actual_name | |
find_data_file | asked_name | actual_name | |
find_opentype_file | asked_name | actual_name | |
find_truetype_file | asked_name | actual_name | |
find_type_file | asked_name | actual_name | |
find_image_file | asked_name | actual_name |
File reading callbacks
The previous callbacks were called when a file was asked for; the following are triggered when the file is read. In all, filename is the string returned by the file discovery callbacks. The first callback reads \input or \read files; it must return a table, whose first cell is a function that will be called whenever a line from the input file is readed; the second cell is an optional function executed when the input file terminates.
The other callbacks are used for binary files: success is a boolean, data is a string and data_size is a number (the length of data in bytes).
Name | Argument(s) | Return value(s) | Short description |
---|---|---|---|
open_read_file | filename | {reader, close} | |
read_font_file | filename | success, data, data_size | |
read_vf_file | filename | success, data, data_size | |
read_map_file | filename | success, data, data_size | |
read_enc_file | filename | success, data, data_size | |
read_sfd_file | filename | success, data, data_size | |
read_pk_file | filename | success, data, data_size | |
read_data_file | filename | success, data, data_size | |
read_truetype_file | filename | success, data, data_size | |
read_type1_file | filename | success, data, data_size | |
read_opentype_file | filename | success, data, data_size |
Data processing callbacks
Name | Argument(s) | Return value(s) | Short description |
---|---|---|---|
process_input_buffer | line | modified_line | Called for each input line (after reader in open_read_file if TeX is not reading the main file). |
process_output_buffer | line | modified_line | Called for each line TeX writes to an external file; this excludes the log file, the terminal and \write18 calls. |
token_filter | token | Called when TeX needs token; no argument is passed to the callback, the next token must be fetched with token.get_next(); what is returned is immediately processed by TeX. |
Node list processing callbacks
These callbacks deal with node manipulations and occur at various stages of TeX's typesetting processes.
Name | Argument(s) | Return value(s) | Short description |
---|---|---|---|
buildpage_filter | information | Called when TeX moves material to the main vertical list. (This callback is an endangered species.) | |
hyphenate | head, tail | Inserts discretionary nodes in the node list; called in restricted and unrestricted horizontal mode (i.e. \hbox'es and paragraph building). A function doing what TeX does here by default is lang.hyphenate(). | |
ligaturing | head, tail | Same as hyphenate, but applying ligatures (and adding some discretionaries too). An associated function is node.ligaturing(). | |
kerning | head, tail | Same as above, with font kerns. The associated function is node.kerning(). | |
pre_linebreak_filter | head, context | boolean or newhead | Called in unrestricted horizontal mode, after kerning, and before calling the paragraph builder; it receives the list of nodes that is the contents of the paragraph (plus the \parfillskip glue) and must return something similar. |
linebreak_filter | head, is_display | newhead | The paragraph builder. It receives what the previous callback has returned and is in charge of making a paragraph out of it; it must return what it has built. An associated function is tex.linebreak(). |
post_linebreak_filter | head, groupcode, | boolean or newhead | Receives what has been returned by linebreak_filter and must return something similar. |
hpack_filter | head, context, size, packtype[, dir] | boolean or newhead | Called when TeX is going to build an \hbox. |
vpack_filter | head, context, size, packtype, maxdepth[, dir] | boolean or newhead | Called when TeX is going to build a \vbox. |
pre_output_filter | head, context, size, packtype, maxdepth[, dir] | boolean or newhead | Same as vpack_filter, but when TeX packs box 255 (or any other value of \outputbox) and goes to the output routine. |
mlist_to_hlist | head, display_type, need_penalties | newhead | Called when TeX turns a math list into a horizontal list (as described in Appendix G of the TeXbook). |
Information reporting callbacks
These callbacks are called in various places when TeX has something to say. None of them takes an argument nor returns anything.
Name | Short description |
---|---|
pre_dump | Called before dumping a format. |
start_run | LuaTeX's banner (`This is LuaTeX...'); must be changed in the initialization script, otherwise the banner has already been printed. |
stop_run | TeX's final words (statistics and `Output written to...'). |
start_page_number | The opening bracket and the page number printed when a page is shipped out. |
stop_page_number | The closing bracket printed after the previous callback. |
show_error_hook | Called at the beginning of each error message. |
Miscellaneous
Name | Argument(s) | Return value(s) | Short description |
---|---|---|---|
finish_pdffile | Called when all pages have been written to the PDF file. | ||
define_font | name, size, id | font_table | Called when the \font command is executed; name is the filename asked for, size is the at size, id is the number that will be assigned as an internal representation to the font thus loaded. The callback should return a table representing a font. |