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
241
242
243
244
245
246
247
248
249
250
251
252
253
|
\input minim-doc.sty
\chapter Programming macros
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.
If you want to access from lua a register defined in tex, the function
⟦*M.registernumber('name')⟧ will give you the index of register ⟦\name⟧.
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')⟧.
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. Its interface matches the primitive interface,
with ⟦*C.register(callback, fn)⟧, ⟦*C.find(callback)⟧ and ⟦*C.list()⟧ taking
the same arguments. In addition to these, ⟦*C.deregister(fn)⟧ will allow you to
remove a callback. This is necessary when you want to remove a callback from
a list or from the bottom of a stack. The ⟦fn⟧ variable should point to the
same object.
Any callbacks that are already assigned before loading this module will be
preserved and the primitive callback interface is still available, though
callbacks registered through the latter will actually use the new functions.
Ltluatex may be loaded either before or after this module.
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⟧.
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
⟦uselanguage⟧,
⟦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.
Two callbacks are new:
the new ⟦*mlist_to_mlist⟧ callback is called before ⟦mlist_to_hlist⟧ and should
not convert noads to nodes, while the ⟦*uselanguage⟧ callback is called from
⟦\uselanguage⟧.
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 Programming helpers
Optional keyword arguments to tex macros can be defined with help of
⟦*M.options_scanner()⟧. An example from the definition of minim-pdf’s
⟦\outline⟧:
⟦ local s = M.options_scanner()
:keyword('open', 'closed')
:string('dest')
:scan()
s.title = token.scan_string()
M.add_bookmark(s)⟧
Here, the ⟦keyword⟧ function adds two opposite keywords: if one is present, its
value will be set to ⟦true⟧ and the other’s to ⟦false⟧ (the second keyword is
optional). The ⟦string⟧ function stores the result of ⟦token.scan_string⟧ under
its key. Of the same form you have ⟦int⟧, ⟦glue⟧, ⟦dimen⟧, ⟦argument⟧, ⟦word⟧
and ⟦list⟧. All these take an optional second argument: if ⟦true⟧ then the
keyword can be repeated and its values will be stored as a list.
The ⟦scan⟧ function, finally, scans all keywords, which may appear in any
order. You can give it a table with default values. In the example given above,
the argument ⟦s⟧ to ⟦M.add_bookmark⟧ will consist of a table with at most the
following entries: ⟦open⟧, ⟦closed⟧, ⟦dest⟧ and ⟦title⟧, though entries whose
keywords do not occur will not be present.
This function is particularly useful when used together with
⟦*M.luadef('csname', function, ...)⟧, which defines primitive-like tex macros
from lua. There, ⟦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'⟧.
\section Miscellaneous functions
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.
Both ⟦*M.unset⟧ and ⟦*\unset⟧ contain the value ⟦-0x7FFFFFFF⟧ that can be used
for clearing attributes.
When writing data to pdf literals, ⟦*M.pdf_string(...)⟧,
⟦*M.pdf_name(...)⟧ and ⟦*M.pdf_date(...)⟧ may be useful: they produce strings
that can be written to the pdf directly. Surrounding ⟦<>⟧ or ⟦()⟧ characters or
a leading ⟦/⟧ will be included in the return value. The ⟦M.pdf_date⟧ function
expects a value of the form ⟦yyyy[-mm[-dd]]⟧ and returns a date of the form
⟦(D:yyyymmdd)⟧.
The function ⟦M.pdf_string⟧ is also available to tex through the macro
⟦*\pdfstring⟧.
Finally the function ⟦*M.table_to_text(table)⟧ may be useful when debugging lua
code: it dumps a table as a (lua-readable) string. Cyclic references will spin
in into an eternal loop, however.
\section Miscellaneous helper macros
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
|