diff options
Diffstat (limited to 'macros/luatex/generic/minim/minim-alloc.doc')
-rw-r--r-- | macros/luatex/generic/minim/minim-alloc.doc | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/macros/luatex/generic/minim/minim-alloc.doc b/macros/luatex/generic/minim/minim-alloc.doc new file mode 100644 index 0000000000..fa08988bf4 --- /dev/null +++ b/macros/luatex/generic/minim/minim-alloc.doc @@ -0,0 +1,216 @@ + +\input minim-doc.sty + +This chapter describes the programming helper modules on which all the above +modules depend. It mainly concerns register allocation, callback management and +format file inclusion. + +They can be loaded separately by saying ⟦\input minim-alloc⟧; +thereafter, you can use ⟦local M = require('minim-alloc')⟧ to access the lua +interface. +In this chapter, when discussing lua functions, you are assumed to have issued +the latter statement, so that the table ⟦M⟧ refers to the contents of this +module. + +The callback-related code lives in a separate file that can and must be loaded +separately as ⟦local C = require('minim-callbacks')⟧. This is the only file in +this collection that does not itself depend on the minim-alloc module. + +There is a large functional overlap between this module and the ltluatex +package. You can use both at the same time, however, and the order in which you +load both packages should not matter. + +\section Format files + +A major motivation for writing this module (and not, instead, depending on +⟦ltluatex.tex⟧) is the ability to write lua-heavy code that can be safely +included in format files. +For this purpose, the register allocation functions described below allow +ensuring that the allocation is made only once. + +Apart from registers, you need only do two more things to make your code format +file safe. The first is saying ⟦*M.remember('your-file.lua')⟧ somewhere, +anywhere. This will mark your file for inclusion in the format. At the start of +every job, all remembered files will be executed (in order) and their return +values will be stored to be retrieved whenever you say ⟦require('your-file')⟧. +Note that while this feature does not improve speed in any meaningful way, it +will ensure the lua file used by the format is identical to the one used to +create it. + +It does mean, however, that your file may be executed twice: once when building +the format and once when the format is used. In most cases (e.g. callback +registration) this is exactly what you want. +Sometimes however, you may need to store variable (configurable) data in the +format file. +You can do this by saying +⟦*local t = M.saved_table('identifier', default-table)⟧. +This will retrieve the table from the format file if possible; otherwise, it +will return ⟦default-table⟧ and mark it to be saved to the format. A missing +second argument is equivalent to an empty table. +Saved tables may only contain (arbitrary but non-cyclic nestings of) tables, +numbers and strings. + +\section Register allocation + +For allocating the new luatex registers, you can use the following: +⟦*\newfunction⟧, +⟦*\newattribute⟧, +⟦*\newwhatsit⟧, +⟦*\newluabytecode⟧, +⟦*\newluachunkname⟧, +⟦*\newcatcodetable⟧ and +⟦*\newuserrule⟧. +Note the one difference with ltluatex, which has ⟦\newluafunction⟧ instead. +(The reason for this is that ltluatex, instead of a more sensible method, uses +this macro for determining whether it has been read before.) +Internally, the very same counts are used for keeping track of register +allocation as in ltluatex. +Their effect should therefore be identical in all circumstances, with one +exception: +no bounds checking is performed on any allocation macro defined by minim. +Please do not go and use more than sixty five thousand different whatsits. + +All the above and all traditional registers can be allocated from within lua as +well, using ⟦*M.new_count('name')⟧, ⟦*M.new_whatsit('name')⟧ etc. All return +the allocated number. The (optional) string ⟦name⟧ prevents the same allocation +from being made twice: if another register has been retrieved with the same +name, the number of that register will be returned. You will need this when you +want to allow your lua code to be included in a format file; it has nothing to +do with the tex-side ⟦\countdef⟧ and the like. + +For the new allocation macros listed above and (as a special case) for +⟦\newbox⟧, +after saying ⟦\newwhatsit\name⟧, the call ⟦M.new_whatsit('name')⟧ will return +the number of ⟦\name⟧. For the other (older) allocation macros, this is not the +case. After all, because of the ⟦\countdef⟧ etc. included in ⟦\newcount⟧ etc. +you can already use ⟦tex.count['name']⟧ etc. for retrieving tex-side +allocations from lua. The exceptions to this are ⟦\newbox⟧, which is why it is +included with the new macros, and ⟦\newattribute⟧, for which you can use both +methods. + +Besides ⟦\newluachunkname\name⟧, you can also use +⟦*\setluachunkname \name {actual name}⟧ +to enter the value of the name directly. + +Finally, for the registers for which etex defines a local allocation macro (and +for those only), you can use ⟦*M.local_count()⟧ etc. These allocation functions +take no parameters. + + +\section Callbacks + +As noted at the beginning of this chapter, the callback functions are only +available after you say ⟦local C = require('minim-callbacks')⟧. + +This module will override the primitive callback functions with its own +⟦*C.register⟧, ⟦*C.find⟧ and ⟦*C.list⟧; the original primitive functions can be +found in the ⟦*C.primitives⟧ table. + +The simple function of this module is allowing multiple callbacks to co-exist. +Different callbacks call for different implementations, and some callbacks can +only contain a single function. +Any callbacks that are already assigned before loading this module will be +preserved; this includes the ltluatex callback mechanism if it has already been +installed. + +You can create your own callbacks with ⟦*C.new_callback(name, type)⟧. The ⟦type⟧ +should be one of the types mentioned below or ⟦'single'⟧ for callbacks that +allow only one function. If the ⟦name⟧ is that of a primitive callback, new +registrations will target your new callback. +You can call the new callback with ⟦*C.call_callback(name, ...)⟧, adding any +number of parameters. + +Callbacks of type ⟦*node⟧ operate on a node list: for these, all registered +functions will be called in order, each function receiving the result of the +last. +After one function returns ⟦false⟧, no others will be called. +Callbacks of this type are +⟦pre_linebreak_filter⟧, +⟦post_linebreak_filter⟧, +⟦hpack_filter⟧, +⟦vpack_filter⟧, +⟦pre_output_filter⟧ and +⟦mlist_to_mlist⟧. +There is no way of unregistering callbacks of this type. + +Similarly, for the ⟦*data⟧ callbacks +⟦process_input_buffer⟧, +⟦process_output_buffer⟧ and +⟦process_jobname⟧, +all registered functions will be called in order on the output of the previous. +Returning ⟦false⟧ will in this case result in the output of the previous +function passing to the next. + +For ⟦*stack⟧ callbacks, a stack is kept and only the top function on the stack +will be called. These are +⟦mlist_to_hlist⟧, +⟦hpack_quality⟧, +⟦vpack_quality⟧, +⟦hyphenate⟧, +⟦linebreak_filter⟧, +⟦buildpage_filter⟧ and +⟦build_page_insert⟧. +Register ⟦nil⟧ at the callback to pop a function off the stack. + +Finally, for the ⟦*simple⟧ callbacks +⟦contribute_filter⟧, +⟦pre_dump⟧, +⟦wrapup_run⟧, +⟦finish_pdffile⟧, +⟦finish_pdfpage⟧, +⟦insert_local_par⟧, +⟦ligaturing⟧, +⟦kerning⟧ and +⟦process_rule⟧. +all registered functions are called in order with the same arguments. + +The new ⟦*mlist_to_mlist⟧ callback is called before ⟦mlist_to_hlist⟧ and should +not convert noads to nodes. + +If you create a new callback with a number for a name, that callback will +replace the ⟦*process_rule⟧ callback when its number matches the index property +of the rule. + + +\section Miscellaneous functions + +This section describes functions and macros that are internal to this package, +but might be of general usefulness. + +For instance, you might find the function ⟦*M.table_to_text(table)⟧ useful when +debugging lua code. +The small functions +⟦*M.msg(...)⟧, ⟦*M.log(...)⟧ and ⟦*M.err(...)⟧ +include a call to ⟦M.string.format⟧; +additionally, +⟦*M.amsg(...)⟧ and ⟦*M.alog(...)⟧ +do not start a new line. + +Very useful is ⟦*M.luadef('csname', function, ...)⟧ for defining primitive-like +tex macros from lua: ⟦function⟧ can be any function (it will be assigned a lua +function register) and at the place of the dots you may append ⟦'protected'⟧ +and/or ⟦'global'⟧. + +Both ⟦*M.unset⟧ and ⟦*\unset⟧ contain the value ⟦-0x7FFFFFFF⟧ that can be used +for clearing attributes. + +On the tex side, ⟦*\voidbox⟧, ⟦*\ignore⟧, ⟦*\spacechar⟧, ⟦*\unbrace⟧, +⟦*\firstoftwo⟧ and ⟦*\secondoftwo⟧ should be self-explanatory and +uncontroversial additions. For looking ahead, you can use +⟦*\nextif \token {executed if present} {executed if not}⟧ +or its siblings ⟦*\nextifx⟧ and ⟦*\nextifcat⟧. +For defining macros with optional arguments, ⟦*\withoptions[default]{code}⟧ +will ensure something within square brackets follows ⟦code⟧. + +Finally, ⟦*\splitcommalist {code} {list}⟧ will apply ⟦code⟧ to every nonempty +item on a comma-separated ⟦list⟧. +Items of the list will be re-tokenised and have surrounding spaces removed. +This macro is fully expandable. + +Because of their usefulness and simplicity, these macros have been made +available without special characters in their names; I hope you can tolerate +their presence. Please let me know if their names clash with something +important. + +\endinput + |