luametatex-callbacks.tex /size: 48 Kb    last modification: 2025-02-21 11:03
1% language=us runpath=texruns:manuals/luametatex
2
3\environment luametatex-style
4
5\startdocument[title=Callbacks]
6
7\startsection[title={Introduction}]
8
9Right from the start of the \LUATEX\ project callbacks were the way to extend the
10engine. At various places in processing the document source and typesetting the
11text the engine checks if there is a callback set and if so, calls out to \LUA.
12Here we collect the various callbacks. For examples you can consult the \CONTEXT\
13code base.
14
15The \type {callback} library has functions that register, find and list
16callbacks. Callbacks are \LUA\ functions that are called in well defined places.
17There are two kinds of callbacks: those that mix with existing functionality, and
18those that (when enabled) replace functionality. In most cases the second
19category is expected to behave similar to the built in functionality because in a
20next step specific data is expected. For instance, you can replace the
21hyphenation routine. The function gets a list that can be hyphenated (or not).
22The final list should be valid and is (normally) used for constructing a
23paragraph. Another function can replace the ligature builder and|/|or kern
24routine. Doing something else is possible but in the end might not give the user
25the expected outcome.
26
27In order for a callback to kick in you need register it. This can be permanent or
28temporarily.
29
30\starttyping[option=LUA]
31id = callback.register(<t:string> callback_name, <function> func)
32id = callback.register(<t:string> callback_name, nil)
33id = callback.register(<t:string> callback_name, false)
34\stoptyping
35
36Here the \type {callback_name} is a predefined callback name as discusses in
37following sections. The function returns the internal \type {id} of the callback
38or \type {nil}, if the callback could not be registered. \LUAMETATEX\
39internalizes the callback function in such a way that it does not matter if you
40redefine a function accidentally.
41
42Callback assignments are always global. You can use the special value \type {nil}
43instead of a function for clearing the callback.
44
45For some minor speed gain, you can assign the boolean \type {false} to the
46non|-|file related callbacks, doing so will prevent \LUATEX\ from executing
47whatever it would execute by default (when no callback function is registered at
48all). {\em This needs checking.}
49
50\starttyping[option=LUA]
51<table> info = callback.list()
52\stoptyping
53
54The keys in the table are the known callback names, the value is a boolean where
55\type {true} means that the callback is currently set (active).
56
57\starttyping[option=LUA]
58<function> f = callback.find(callback_name)
59\stoptyping
60
61If the callback is not set, \type {find} returns \type {nil}. The \type {known}
62function can be used to check if a callback is supported.
63
64\starttyping[option=LUA]
65if callback.known("foo") then
66    -- do what is needed
67end
68\stoptyping
69
70\stopsection
71
72\startsection[title=Files]
73
74\startsubsection[title=find_log_file]
75
76This is one of the callbacks that has to be set in order for the engine to work
77at all.
78
79\starttyping[option=LUA]
80function (
81    <t:string> askedname
82)
83    return <t:string> foundname
84end
85\stoptyping
86
87\stopsubsection
88
89\startsubsection[title=find_format_file]
90
91A format file is an efficient memory dump of the (in our case \CONTEXT) macro
92package. In \LUATEX\ it can have a mix of \TEX and \LUA\ code but one should be
93aware that storing the \LUA\ state is not up to the engine.
94
95\starttyping[option=LUA]
96function (<t:string> askedname)
97    return <t:string> foundname
98end
99\stoptyping
100
101A format file can be read from any valid location but is always written in the
102current directory. When written the number of bytes for each section is reported.
103When read all kind of checks take place ijn order to intercept corruption or
104incompatibilities. Contrary to \LUATEX, the \LUAMETATEX\ is not (zip) compressed so,
105in spite of more aggressive compression of data otherwise the file is a bit larger.
106
107\stopsubsection
108
109\startsubsection[title=open_data_file]
110
111This callback function gets a filename passed. The return value is either the boolean
112value false or a table with two functions. A mandate \type {reader} function fill be
113called once for each new line to be read, the optional \type {close} function will
114be called once \LUATEX\ is done with the file.
115
116\starttyping[option=LUA]
117function (
118    <t:string> filename
119)
120    return <table> {
121        <function> reader(<table> environment) end,
122        <function> close (<table> environment) end,
123    }
124end
125\stoptyping
126
127\LUAMETATEX\ never looks at the rest of the table, so we can use it to store
128additional per|-|file data. Both the callback functions will receive the table as
129their only argument.
130
131\stopsubsection
132
133\startsubsection[title=start_file]
134
135This callback replaces the code that \LUAMETATEX\ prints when a file is opened like
136\type {(filename} for regular files. The category is a number:
137
138\starttyping[option=LUA]
139function (
140    <t:integer> category,
141    <t:string>  filename
142)
143    -- no return values
144end
145\stoptyping
146
147The following categories can occur:
148
149\starttabulate[|c|l|]
150% \DB value  \BC meaning \NC \NR
151% \TB
152\FL
153\BC value  \BC meaning \NC \NR
154\ML
155\NC 1 \NC a normal data file, like a \TEX\ source \NC \NR
156\NC 2 \NC a font map coupling font names to resources \NC \NR
157\NC 3 \NC an image file (\type {png}, \type {pdf}, etc) \NC \NR
158\NC 4 \NC an embedded font subset \NC \NR
159\NC 5 \NC a fully embedded font \NC \NR
160\LL
161\stoptabulate
162
163\stopsubsection
164
165\startsubsection[title=stop_file]
166
167This callback replaces the code that \LUAMETATEX\ prints when a file is closed like
168the \type {)} for regular files.
169
170\starttyping[option=LUA]
171function (
172    <t:integer> category
173)
174    -- no return values
175end
176\stoptyping
177
178\stopsubsection
179
180\stopsection
181
182\startsection[title=Running]
183
184\startsubsection[title=process_jobname]
185
186This callback allows you to change the jobname given by \type {\jobname} in \TEX\
187and \type {tex.jobname} in \LUA. It does not affect the internal job name or the
188name of the output or log files.
189
190\starttyping[option=LUA]
191function (
192    <t:string> jobname
193)
194    return <t:string> adjusted_jobname
195end
196\stoptyping
197
198The only argument is the actual job name; you should not use \type {tex.jobname}
199inside this function or infinite recursion may occur. If you return \type {nil},
200\LUAMETATEX\ will pretend your callback never happened. This callback does not
201replace any internal code.
202
203\stopsubsection
204
205\startsubsection[title=pre_dump]
206
207This function is called just before dumping to a format file starts. It does not
208replace any code and there are neither arguments nor return values. It can be used to do some
209cleanup and other housekeeping.
210
211\starttyping[option=LUA]
212function (
213    -- no arguments
214)
215    -- no return values
216end
217\stoptyping
218
219\stopsubsection
220
221\startsubsection[title=start_run]
222
223\starttyping[option=LUA]
224function(
225    -- no arguments
226)
227    -- no return values
228end
229\stoptyping
230
231This callback replaces the code that prints \LUATEX's banner. Note that for
232successful use, this callback has to be set in the \LUA\ initialization script,
233otherwise it will be seen only after the run has already started.
234
235\stopsubsection
236
237\startsubsection[title=stop_run]
238
239\starttyping[option=LUA]
240function(
241    -- no arguments
242)
243    -- no return values
244end
245\stoptyping
246
247This callback replaces the code that prints \LUATEX's statistics and \quote
248{output written to} messages. The engine can still do housekeeping and therefore
249you should not rely on this hook for postprocessing the \PDF\ or log file.
250
251\stopsubsection
252
253\startsubsection[title=intercept_tex_error]
254
255This callback is run from inside the \TEX\ error function, and the idea is to
256allow you to do some extra reporting on top of what \TEX\ already does (none of
257the normal actions are removed). You may find some of the values in the \type
258{status} table useful. The \TEX\ related callback gets two arguments: the current
259processing mode and a boolean indicating if there was a runaway.
260
261
262\starttyping[option=LUA]
263function (
264    -- no arguments
265)
266    -- no return values
267end
268\stoptyping
269
270\stopsubsection
271
272\startsubsection[title=intercept_lua_error]
273
274This callback is similar to the one discussed in the previous section but for
275\LUA. Of course we should in a recoverable state for this to work well.
276
277\starttyping[option=LUA]
278function (
279    -- no arguments
280)
281    -- no return values
282end
283\stoptyping
284
285\stopsubsection
286
287\startsubsection[title=show_error_message]
288
289This callback replaces the code that prints the error message. The usual
290interaction after the message is not affected but it is best to quit the run
291after reporting.
292
293\starttyping[option=LUA]
294function (
295    -- no arguments
296)
297    -- no return values
298end
299\stoptyping
300
301\stopsubsection
302
303\startsubsection[title=show_warning_message]
304
305This callback replaces the code that prints a (non fatal) warning message. The
306usual interaction after the message is not affected.
307
308\starttyping[option=LUA]
309function (
310    -- no arguments
311)
312    -- no return values
313end
314\stoptyping
315
316\stopsubsection
317
318\startsubsection[title=wrapup_run]
319
320
321This callback is called after the \PDF\ and log files are closed. Use it at your own
322risk. efine_f
323risk.
324
325\starttyping[option=LUA]
326function (
327    -- no arguments
328)
329    -- no return values
330end
331\stoptyping
332
333\stopsubsection
334
335\startsubsection[title=handle_overload]
336
337One characteristic of \TEX\ is that you have quite some control over what a
338control sequence triggers. For instance, \type {\hbox} normally starts a
339horizontal box but a user can redefine this primitive as macro to do whatever is
340required. This means that when other macros use this primitive their behavior
341will change. One way out of this is using aliases, for instance:
342
343\starttyping
344\normalsetbox0\normalhbox{test}
345\normalifdim\normalwd0>10pt \normalbox0 \normalfi
346\stoptyping
347
348But even these normal aliases can be redefined. Of course you can use special
349characters like \type {_} in names but once you start doing this:
350
351\starttyping
352\p_setbox0\p_hbox{test}
353\p_ifdim\p_wd0>10pt \p_box0 \p_fi
354\stoptyping
355
356you should wonder if you still offer the user \TEX\ as a programming language.
357It's not the route that \CONTEXT\ takes.
358
359In \LUAMETATEX\ every macro (including primitives) can be flagged and that happens
360with so called prefixes. Traditional \TEX\ offers:
361
362\starttyping
363\global\def\foo{...}
364\long  \def\foo{...} % no-op
365\outer \def\foo{...} % no-op
366\stoptyping
367
368The \type {\long} and \type {\outer} made sense at that time but are no-ops in
369\LUAMETATEX: every macro can take \type {\par} equivalents as arguments and can
370be \ defined at every level. The \ETEX\ extensions introduced this prefix:
371
372\starttyping
373\protected\def\foo{...}
374\stoptyping
375
376which prevents expansion unless the value is really expected (needed). The
377\LUAMETATEX\ engine added:
378
379\starttyping
380\semiprotected\def\foo{...}
381\stoptyping
382
383but when eventually I see no reason to use it in \CONTEXT\ it might be dropped. A
384special prefix is:
385
386\starttyping
387\constant\def\foo{...}
388\stoptyping
389
390This effectively is equivalent to \type {\edef} but signals that in some
391scenarios (like an \type {\csname} equivalent situation) no expansion and
392checking has to happen which improves performance.
393
394These two prefixes are just signals to \LUA\ driven functionality:
395
396\starttyping
397\deferred  \foo
398\immediate \foo
399\stoptyping
400
401The prefixes do nothing except when \type {\foo} are \LUA\ calls that can use
402this information to adapt behavior. Because we have no backend the macro package
403has to come up with equivalents for e.g.\ \type {\write} than can be immediate or
404deferred (default) operations.
405
406Another prefix relates to alignments:
407
408\starttyping
409\noaligned\protected\def\foo{...}
410\stoptyping
411
412Which makes a macro accepted between alignment rows where otherwise protected
413macros will trigger an error due to look ahead.
414
415A definition with \type {\def} or \type {\gdef} can take arguments and these can be
416made optional with:
417
418\starttyping
419\def\tolerant[#1]{...}
420\stoptyping
421
422but there are more features related to tolerant:
423
424\starttyping
425\def\tolerant[#1]#*[#2]{...}
426\stoptyping
427
428that are discusses in low level manuals. Users can define macros that are
429reported (in tracing) as if they were primitives:
430
431\starttyping
432\untraced\protected\def\foo{...}
433\stoptyping
434
435The prefixes \type {\constrained} and \type {\retained} relate to register values
436being saved and restored in groups. The \type {\inherited} is used in for
437instance math spacing assignments where we need dynamic binding to for instance
438\type {\muskip} registers (instead of values).
439
440Although not related to the callback discussed here we mentioned these prefixes because
441they belong to the \type {prefixed_cmd} operator|/|operand pair. So to come back to
442users being able to use primitives instead of funny unreadable aliases. It's good to
443keep in  mind that one can combine prefixes like the following:
444
445\starttyping
446\frozen    \foo{...}
447\immutable \foo{...}
448\instance  \foo{...}
449\mutable   \foo{...}
450\overloaded\foo{...}
451\permanent \foo{...}
452\stoptyping
453
454so this is valid too:
455
456\starttyping
457\global\permanent\untraced\tolerant\protected\def\foo[#1]#*[#2]{...}
458\stoptyping
459
460So what do these prefixes do? It depends on the value of an internal
461integer \type {\overloadmode} where the following values have meaning:
462
463\starttabulate[|c|l|c|c|c|c|c|]
464% \DB   \BC         \BC immutable \BC permanent \BC primitive \BC frozen \BC instance \NC \NR
465% \TB
466\FL
467\BC   \BC         \BC immutable \BC permanent \BC primitive \BC frozen \BC instance \NC \NR
468\ML
469\NC 1 \NC warning \NC \star     \NC \star     \NC \star     \NC        \NC          \NC \NR
470\NC 2 \NC error   \NC \star     \NC \star     \NC \star     \NC        \NC          \NC \NR
471\NC 3 \NC warning \NC \star     \NC \star     \NC \star     \NC \star  \NC          \NC \NR
472\NC 4 \NC error   \NC \star     \NC \star     \NC \star     \NC \star  \NC          \NC \NR
473\NC 5 \NC warning \NC \star     \NC \star     \NC \star     \NC \star  \NC \star    \NC \NR
474\NC 6 \NC error   \NC \star     \NC \star     \NC \star     \NC \star  \NC \star    \NC \NR
475\LL
476\stoptabulate
477
478The \type {\enforced} prefix can be used to bypass this mechanism:
479
480\starttyping
481\permanent\protected\def\foo{...}
482
483\protected\def\oof{\enforced\def\foo{...}}
484\stoptyping
485
486But only in so called quote {ini} mode, that is when the format file is created. In order to
487save work we also have:
488
489\starttyping
490\aliased\let\foo\relax
491\stoptyping
492
493This makes \type {\foo} a copy (or more precise, a reference) including all
494flags, so in this case it will be flagged a a primitive which is \type
495{\permanent} too. You cannot define primitives yourself but when reported in a
496trace you see it being a primitive indeed.
497
498Of course this all means that one has to define basically all relevant macros
499with a combination of prefixes and that happens to be the case in \CONTEXT, which
500in the end makes this callback a rather \CONTEXT\ specific one.
501
502\starttyping[option=LUA]
503function (
504    <t:boolean> error,
505    <t:integer> overload,
506    <t:string>  csname,
507    <t:integer> flags
508)
509    -- no return values
510end
511\stoptyping
512
513\stopsubsection
514
515\stopsection
516
517\startsection[title=Fonts]
518
519\startsubsection[title=define_font]
520
521The engine has no font loader but it does need some information about the glyphs
522that are uses like width, height and depth, possibly italic correction, kerns,
523and ligatures. And for math some more information is needed. Keep in mind that
524for instance italic correction is something specific for \TEX\ and that kerns and
525ligatures only are needed when you leave them to the engine. For modern \OPENTYPE\ fonts
526we let \LUA\ deal with this.
527
528\starttyping[option=LUA]
529function (
530    <t:string>  name,
531    <t:integer> size
532)
533    return <t:integer> id
534end
535\stoptyping
536
537The string \type {name} is the filename part of the font specification, as given
538by the user, for instance when \type {\font} is used for defining an instance.
539The number \type {size} is a bit special:
540
541\startitemize[packed]
542\startitem
543    If it is positive, it specifies an \quote{at size} in scaled points.
544\stopitem
545\startitem
546    If it is negative, its absolute value represents a \quote {scaled} setting
547    relative to the design size of the font.
548\stopitem
549\stopitemize
550
551The font can be defined with \type {font.define} which returns a font identifier
552that can be returned in the callback. Contrary to \LUATEX, in \LUAMETATEX\
553we only accept a number.
554
555The internal structure of the \type {font} table that is passed to \type
556{font.define} is explained elsewhere but there can be much more in that table.
557Likely the macro package will keep the passes table around for other usage, for
558instance for usage in the backend.
559
560Setting this callback to \type {false} is pointless because it will prevent font
561loading completely because without fonts there is little to do for the engine.
562
563\stopsubsection
564
565\startsubsection[title=quality_font]
566
567When you use font expansion you will normally pass the glyph specific expansion and
568compression values along with the dimensions. However, this can be delayed. When we
569use par passes (or otherwise set one of the adjust parameters) and a font has not
570yet bee setup for expansion this callback will kick in but only once per font.
571
572\starttyping[option=LUA]
573function (
574    <t:integer> id
575)
576    -- no return values
577end
578\stoptyping
579
580The function can set additional parameters in the font and pass them to \TEX\ using
581helpers from the font library.
582
583\stopsubsection
584
585\stopsection
586
587\startsection[title=Typesetting]
588
589\startsubsection[title=pre_output_filter]
590
591This callback is called when \TEX\ is ready to start boxing the box 255 for \prm
592{output}. The callback does not replace any internal code.
593
594\starttyping[option=LUA]
595function (
596    <t:node>    head,
597    <t:string>  groupcode,
598    <t:integer> size,
599    <t:string>  packtype,
600    <t:integer> maxdepth,
601    <t:integer> direction
602)
603    return <t:node> newhead
604end
605\stoptyping
606
607\stopsubsection
608
609\startsubsection[title=buildpage_filter]
610
611This callback is called whenever \LUAMETATEX\ is ready to move stuff to the main
612vertical list. You can use this callback to do specialized manipulation of the
613page building stage like imposition or column balancing.
614
615\starttyping[option=LUA]
616function (
617    <t:string> extrainfo
618)
619    -- no return values
620end
621\stoptyping
622
623The string \type {extrainfo} gives some additional information about what \TEX's
624state is with respect to the \quote {current page}. The possible values for this
625callback are:
626
627\starttabulate[|l|p|]
628% \DB value                 \BC explanation                                 \NC \NR
629% \TB
630\FL
631\BC value                 \BC explanation                                 \NC \NR
632\ML
633\NC \type{alignment}      \NC a (partial) alignment is being added        \NC \NR
634\NC \type{after_output}   \NC an output routine has just finished         \NC \NR
635\NC \type{new_graf}       \NC the beginning of a new paragraph            \NC \NR
636\NC \type{vmode_par}      \NC \type {\par} was found in vertical mode     \NC \NR
637\NC \type{hmode_par}      \NC \type {\par} was found in horizontal mode   \NC \NR
638\NC \type{insert}         \NC an insert is added                          \NC \NR
639\NC \type{penalty}        \NC a penalty (in vertical mode)                \NC \NR
640\NC \type{before_display} \NC immediately before a display starts         \NC \NR
641\NC \type{after_display}  \NC a display is finished                       \NC \NR
642\NC \type{end}            \NC \LUAMETATEX\ is terminating (it's all over) \NC \NR
643\LL
644\stoptabulate
645
646
647\stopsubsection
648
649\startsubsection[title=hpack_filter]
650
651This callback is called when \TEX\ is ready to start boxing some horizontal mode
652material. Math items and line boxes are ignored at the moment. The callback does
653not replace any internal code.
654
655\starttyping[option=LUA]
656function (
657    <t:node>    head,
658    <t:string>  groupcode,
659    <t:integer> size,
660    <t:string>  packtype
661    <t:integer> direction,
662    <t:node>    attributelist
663)
664    return <t:node> newhead
665end
666\stoptyping
667
668The \type {packtype} is either \type {additional} or \type {exactly}. If \type
669{additional}, then the \type {size} is a \type {\hbox spread ...} argument. If
670\type {exactly}, then the \type {size} is a \type {\hbox to ...}. In both cases,
671the number is in scaled points.
672
673\stopsubsection
674
675\startsubsection[title=vpack_filter]
676
677This callback is called when \TEX\ is ready to start boxing some vertical mode
678material. Math displays are ignored at the moment. The callback does not replace
679any internal code.
680
681This function is very similar to \type {hpack_filter}. Besides the fact
682that it is called at different moments, there is an extra variable that matches
683\TEX's \type {\maxdepth} setting.
684
685\starttyping[option=LUA]
686function (
687    <t:node>    head,
688    <t:string>  groupcode,
689    <t:integer> size,
690    <t:string>  packtype,
691    <t:integer> maxdepth,
692    <t:integer> direction,
693    <t:node>    attributelist
694)
695    return <t:node> newhead
696end
697\stoptyping
698
699\stopsubsection
700
701\startsubsection[title=hyphenate]
702
703This callback is supposed to insert discretionary nodes in the node list it
704receives.
705
706\starttyping[option=LUA]
707function (
708    <t:node> head,
709    <t:node> tail
710)
711    -- no return values
712end
713\stoptyping
714
715Setting this callback to \type {false} will prevent the internal discretionary
716insertion pass.
717
718\stopsubsection
719
720\startsubsection[title=ligaturing]
721
722This callback, which expects no return values, has to apply ligaturing to the
723node list it receives.
724
725\starttyping[option=LUA]
726function (
727    <t:node> head,
728    <t:node> tail
729)
730    -- no return values
731end
732\stoptyping
733
734You don't have to worry about return values because the \type {head} node that is
735passed on to the callback is guaranteed not to be a glyph_node (if need be, a
736temporary node will be prepended), and therefore it cannot be affected by the
737mutations that take place. After the callback, the internal value of the \quote
738{tail of the list} will be recalculated.
739
740The \type {next} of \type {head} is guaranteed to be non-nil. The \type {next} of
741\type {tail} is guaranteed to be nil, and therefore the second callback argument
742can often be ignored. It is provided for orthogonality, and because it can
743sometimes be handy when special processing has to take place.
744
745Setting this callback to \type {false} will prevent the internal ligature
746creation pass. You must not ruin the node list. For instance, the head normally
747is a local par node, and the tail a glue. Messing too much can push \LUATEX\ into
748panic mode.
749
750\stopsubsection
751
752\startsubsection[title=kerning]
753
754This callback has to apply kerning between the nodes in the node list it
755receives. See \type {ligaturing} for calling conventions.
756
757\starttyping[option=LUA]
758function (
759    <t:node> head,
760    <t:node> tail
761)
762    -- no return values
763end
764\stoptyping
765
766Setting this callback to \type {false} will prevent the internal kern insertion
767pass. You must not ruin the node list. For instance, the head normally is a local
768par node, and the tail a glue. Messing too much can push \LUATEX\ into panic
769mode.
770
771\stopsubsection
772
773\startsubsection[title=glyph_run]
774
775When set this callback is triggered when \TEX\ normally handles the ligaturing
776and kerning. In \LUATEX\ you use the \typ {hpack_filter} and \typ
777{per_linebreak_filter} callbacks for that (where each passes different
778arguments). This callback doesn't get triggered when there are no glyphs (in
779\LUATEX\ this optimization is controlled by a a variable).
780
781\starttyping[option=LUA]
782function (
783    <t:node>    head,
784    <t:string>  groupcode,
785    <t:integer> direction
786)
787    return <t:node> newhead
788end
789\stoptyping
790
791The traditional \TEX\ font processing is bypassed so you need to take care of that
792with the helpers. (For the moment we keep the ligaturing and kerning callbacks but
793they are kind of obsolete.)
794
795\stopsubsection
796
797\startsubsection[title=pre_linebreak_filter]
798
799This callback is called just before \LUATEX\ starts converting a list of nodes
800into a stack of \type {\hbox}es, after the addition of \type {\parfillskip}. The
801callback does not replace any internal code.
802
803\starttyping[option=LUA]
804function (
805    <t:node>   head,
806    <t:string> groupcode
807)
808    return <t:node> newhead
809end
810\stoptyping
811
812The string called \type {groupcode} identifies the nodelist's context within
813\TEX's processing. The range of possibilities is given in the table below, but
814not all of those can actually appear here, some are for the \type {hpack_filter}
815and \type {vpack_filter} callbacks.
816
817\starttabulate[|l|p|]
818% \DB value                \BC explanation                                     \NC \NR
819% \TB
820\FL
821\BC value                \BC explanation                                     \NC \NR
822\ML
823\NC \type{<empty>}       \NC main vertical list                              \NC \NR
824\NC \type{hbox}          \NC \type {\hbox} in horizontal mode                \NC \NR
825\NC \type{adjusted_hbox} \NC \type {\hbox} in vertical mode                  \NC \NR
826\NC \type{vbox}          \NC \type {\vbox}                                   \NC \NR
827\NC \type{vtop}          \NC \type {\vtop}                                   \NC \NR
828\NC \type{align}         \NC \type {\halign} or \type {\valign}              \NC \NR
829\NC \type{disc}          \NC discretionaries                                 \NC \NR
830\NC \type{insert}        \NC packaging an insert                             \NC \NR
831\NC \type{vcenter}       \NC \type {\vcenter}                                \NC \NR
832\NC \type{local_box}     \NC \type {\localleftbox} or \type {\localrightbox} \NC \NR
833\NC \type{split_off}     \NC top of a \type {\vsplit}                        \NC \NR
834\NC \type{split_keep}    \NC remainder of a \type {\vsplit}                  \NC \NR
835\NC \type{align_set}     \NC alignment cell                                  \NC \NR
836\NC \type{fin_row}       \NC alignment row                                   \NC \NR
837\LL
838\stoptabulate
839
840As for all the callbacks that deal with nodes, the return value can be one of
841three things:
842
843\startitemize
844\startitem
845    boolean \type {true} signals successful processing
846\stopitem
847\startitem
848    \type {<t:node>} signals that the \quote {head} node should be replaced by the
849    returned node
850\stopitem
851\startitem
852    boolean \type {false} signals that the \quote {head} node list should be
853    ignored and flushed from memory
854\stopitem
855\stopitemize
856
857\stopsubsection
858
859\startsubsection[title=linebreak_filter]
860
861This callback replaces \LUATEX's line breaking algorithm. The callback does not
862replace any internal code.
863
864\starttyping[option=LUA]
865function (
866    <t:node>    head,
867    <t:boolean> is_display
868)
869    return <t:node> newhead
870end
871\stoptyping
872
873The returned node is the head of the list that will be added to the main vertical
874list, the boolean argument is true if this paragraph is interrupted by a
875following math display.
876
877If you return something that is not a \type {<t:node>}, \LUATEX\ will apply the
878internal linebreak algorithm on the list that starts at \type {<head>}.
879Otherwise, the \type {<t:node>} you return is supposed to be the head of a list of
880nodes that are all allowed in vertical mode, and at least one of those has to
881represent an \type {\hbox}. Failure to do so will result in a fatal error.
882
883Setting this callback to \type {false} is possible, but dangerous, because it is
884possible you will end up in an unfixable \quote {deadcycles loop}.
885
886\stopsubsection
887
888\startsubsection[title=post_linebreak_filter]
889
890This callback is called just after \LUATEX\ has converted a list of nodes into a
891stack of \type {\hbox}es.
892
893\starttyping[option=LUA]
894function (
895    <t:node>   head,
896    <t:string> groupcode
897)
898    return <t:node> newhead
899end
900\stoptyping
901
902\stopsubsection
903
904\startsubsection[title=append_to_vlist_filter]
905
906This callback is called whenever \LUATEX\ adds a box to a vertical list (the
907\type {mirrored} argument is obsolete):
908
909\starttyping[option=LUA]
910function (
911    <t:node>    box,
912    <t:string>  locationcode,
913    <t:integer> prevdepth
914)
915    return <t:node> list [, <t:integer> prevdepth [, <t:boolean> checkdepth ] ]
916end
917\stoptyping
918
919It is ok to return nothing or \type {nil} in which case you also need to flush
920the box or deal with it yourself. The prevdepth is also optional. Locations are
921\type {box}, \type {alignment}, \type {equation}, \type {equation_number} and
922\type {post_linebreak}. When the third argument returned is \type {true} the
923normal prevdepth correction will be applied, based on the first node.
924
925\stopsubsection
926
927\startsubsection[title=alignment_filter]
928
929This is an experimental callback that when set is called several times during the
930construction of an alignment. The context values are available in \typ
931{tex.getalignmentcontextvalues()}.
932
933\starttyping[option=LUA]
934function (
935    <t:node>   head,
936    <t:string> context,
937    <t:node>   attributes,
938    <t:node>   preamble
939)
940    -- no return values
941end
942\stoptyping
943
944There are no sanity checks so if a user messes up the passed node lists the results
945can be unpredictable and, as with other node related callbacks, crash the engine.
946
947\stopsubsection
948
949\startsubsection[title=local_box_filter]
950
951Local boxes are a somewhat tricky and error prone feature so use this callback
952with care because the paragraph is easily messed up. A line can have a left,
953right and middle box where the middle one has no width. This callback does not
954replace any internal code. The callback gets quite some parameters passed:
955
956\starttyping[option=LUA]
957function (
958    <t:node>    linebox,
959    <t:node>    leftbox,
960    <t:node>    rightbox,
961    <t:node>    middlebox,
962    <t:integer> linenumber,
963    <t:integer> leftskip,
964    <t:integer> rightskip,
965    <t:integer> lefthang,
966    <t:integer> righthang,
967    <t:integer> indentation,
968    <t:integer> parinitleftskip,
969    <t:integer> parinitrightskip,
970    <t:integer> parfillleftskip,
971    <t:integer> parfillrightskip,
972    <t:integer> overshoot
973)
974    -- no return values
975end
976\stoptyping
977
978This is an experimental callback that will be tested in different \CONTEXT\
979mechanisms before it will be declared stable.
980
981\stopsubsection
982
983\startsubsection[title=packed_vbox_filter]
984
985After the \type {vpack_filter} callback (see previous section) is triggered the
986box get packed and after that this callback can be configured to kick in.
987
988\starttyping[option=LUA]
989function (
990    <t:node>   head,
991    <t:string> groupcode
992)
993    return <t:node> newhead
994end
995\stoptyping
996
997\stopsubsection
998
999\startsubsection[title=handle_uleader]
1000
1001The \typ {\uleaders} command inserts a user leader into the list. When a list get packed
1002and has such leaders, a run over the list happens after packing so that it can be
1003finalized.
1004
1005\starttyping[option=LUA]
1006function (
1007    <t:node>    head,
1008    <t:string>  context,
1009    <t:integer> index,
1010    <t:node>    box,
1011    <t:integer> location
1012)
1013    return <t:node> head
1014end
1015\stoptyping
1016
1017\stopsubsection
1018
1019\startsubsection[title=italic_correction]
1020
1021The concept of italic correction is very much related to traditional \TEX\ fonts.
1022At least in 2024 it is absent from \OPENTYPE\ although it has some meaning in
1023\OPENTYPE\ math. In \TEX\ this correction is normally inserted by \type {\/}
1024although in \LUAMETATEX\ we also have \typ {\explicititaliccorrection} as well as
1025\typ {\forcedleftcorrection} and \typ {\forcedrightcorrection}.
1026
1027When this callback is enabled it gets triggered when one of left or right
1028correction commands is given and the returned kern is then used as correction.
1029
1030\starttyping[option=LUA]
1031function (
1032    <t:node>    glyph,
1033    <t:integer> kern,
1034    <t:integer> subtype,
1035)
1036    return <t:integer> kern
1037end
1038\stoptyping
1039
1040\stopsubsection
1041
1042\startsubsection[title=insert_par]
1043
1044Each paragraph starts with a local par node that keeps track of for instance
1045the direction. You can hook a callback into the creator:
1046
1047\starttyping[option=LUA]
1048function (
1049    <t:node>   par,
1050    <t:string> location
1051)
1052    -- no return values
1053end
1054\stoptyping
1055
1056There is no return value and you should make sure that the node stays valid
1057as otherwise \TEX\ can get confused.
1058
1059\stopsubsection
1060
1061\startsubsection[title=append_line_filter]
1062
1063Every time a line is added this callback is triggered, when set. migrated
1064material and adjusts also qualify as such and the detail relates to the adjust
1065index.
1066
1067\starttyping[option=LUA]
1068function (
1069    <t:node>    head,
1070    <t:node>    tail,
1071    <t:string>  context,
1072    <t:integer> detail
1073)
1074    return <t:node> newhead
1075end
1076\stoptyping
1077
1078A list of possible context values can be queried with \typ
1079{tex.getappendlinecontextvalues()}.
1080
1081\stopsubsection
1082
1083\startsubsection[title=insert_distance]
1084
1085This callback is called when the page builder adds an insert. There is not much
1086control over this mechanism but this callback permits some last minute
1087manipulations of the spacing before an insert, something that might be handy when
1088for instance multiple inserts (types) are appended in a row.
1089
1090\starttyping[option=LUA]
1091function (
1092    <t:integer> class,
1093    <t:integer> order
1094)
1095    return <t:integer> register
1096end
1097\stoptyping
1098
1099The return value is a number indicating the skip register to use for the
1100prepended spacing. This permits for instance a different top space (when \type
1101{class} equals one) and intermediate space (when \type {class} is larger than
1102one). Of course you can mess with the insert box but you need to make sure that
1103\LUATEX\ is happy afterwards.
1104
1105\stopsubsection
1106
1107\startsubsection[title=begin_paragraph]
1108
1109Every time a paragraph starts this callback, when configured, will kick in:
1110
1111\starttyping[option=LUA]
1112function (
1113    <t:boolean> invmode,
1114    <t:boolean> indented,
1115    <t:string>  context
1116)
1117    return <t:boolean> indented
1118end
1119\stoptyping
1120
1121There are many places where a new paragraph can be triggered:
1122
1123\startfourrows
1124\getbuffer[engine:syntax:parcontextcodes]
1125\stopfourrows
1126
1127\stopsubsection
1128
1129\startsubsection[title=paragraph_context]
1130
1131When the return value of this callback is \typ {false} the paragraph related
1132settings, when they have been updated, will not be updated.
1133
1134\starttyping[option=LUA]
1135function (
1136    <t:string> context
1137)
1138    return <t:boolean> ignore
1139end
1140\stoptyping
1141
1142\stopsubsection
1143
1144\startsubsection[title=missing_character]
1145
1146This callback is triggered when a character node is created and the font doesn't
1147have the requested character.
1148
1149\starttyping[option=LUA]
1150function (
1151    <t:integer> location,
1152    <t:node>    glyph,
1153    <t:integer> font,
1154    <t:integer> character
1155)
1156    -- no return value
1157end
1158\stoptyping
1159
1160When \prm {tracinglostchars} is set to a positive value a message goes to the log
1161and a value larger than one also makes it show up non the terminal. In the
1162callback, the location is one of:
1163
1164\startfourrows
1165\getbuffer[engine:syntax:missingcharactervalues]
1166\stopfourrows
1167
1168\stopsubsection
1169
1170\startsubsection[title=process_character]
1171
1172This callback is experimental and gets called when a glyph node is created and
1173the callback field in a character is set.
1174
1175\starttyping[option=LUA]
1176function (
1177    <t:integer> font,
1178    <t:integer> character
1179)
1180    -- no return value
1181end
1182\stoptyping
1183
1184\stopsubsection
1185
1186\startsubsection[title=tail_append]
1187
1188%         This callback is called when \LUATEX\ adds contents to list:
1189
1190%         \starttyping[option=LUA]
1191%         function (
1192%             <t:string> extrainfo
1193%         )
1194%         end
1195%         \stoptyping
1196
1197%         The string reports the group code. From this you can deduce from
1198%         what list you can give a treat.
1199
1200%         \starttabulate[|l|p|]
1201%         \DB value             \BC explanation                                  \NC \NR
1202%         \TB
1203%         \NC \type{pre_box}    \NC interline material is being added            \NC \NR
1204%         \NC \type{pre_adjust} \NC \type {\vadjust} material is being added     \NC \NR
1205%         \NC \type{box}        \NC a typeset box is being added (always called) \NC \NR
1206%         \NC \type{adjust}     \NC \type {\vadjust} material is being added     \NC \NR
1207%         \LL
1208%         \stoptabulate
1209
1210\stopsubsection
1211
1212\stopsection
1213
1214\startsection[title=Tracing]
1215
1216\startsubsection[title=hpack_quality]
1217
1218This callback can be used to intercept the overfull messages that can result from
1219packing a horizontal list (as happens in the par builder). The function takes a
1220few arguments:
1221
1222\starttyping[option=LUA]
1223function (
1224    <t:string>  incident,
1225    <t:integer> detail,
1226    <t:node>    head,
1227    <t:integer> first,
1228    <t:integer> last
1229 )
1230    return <t:node> whatever
1231end
1232\stoptyping
1233
1234The incident is one of \type {overfull}, \type {underfull}, \type {loose} or
1235\type {tight}. The detail is either the amount of overflow in case of \type
1236{overfull}, or the badness otherwise. The head is the list that is constructed
1237(when protrusion or expansion is enabled, this is an intermediate list).
1238Optionally you can return a node, for instance an overfull rule indicator. That
1239node will be appended to the list (just like \TEX's own rule would).
1240
1241\stopsubsection
1242
1243\startsubsection[title=vpack_quality]
1244
1245This callback can be used to intercept the overfull messages that can result from
1246packing a vertical list (as happens in the page builder). The function takes a
1247few arguments:
1248
1249\starttyping[option=LUA]
1250function (
1251    <t:string>  incident,
1252    <t:integer> detail,
1253    <t:node>    head,
1254    <t:integer> first,
1255    <t:integer> last
1256)
1257    -- no return values
1258end
1259\stoptyping
1260
1261The incident is one of \type {overfull}, \type {underfull}, \type {loose} or
1262\type {tight}. The detail is either the amount of overflow in case of \type
1263{overfull}, or the badness otherwise. The head is the list that is constructed.
1264
1265\stopsubsection
1266
1267\startsubsection[title=line_break]
1268
1269This callback is actually a set of callbacks that has to be deals with as a
1270whole. The main reason why we have this callback is that we wanted to be able to
1271see what the par builder is doing, especially when we implement multiple
1272paragraph building passes. This makes the callback pretty much a rather \CONTEXT\
1273specific one.
1274
1275{\em We can also consider fetching the passive and active lists because we now keep
1276much more info around.}
1277
1278\starttyping[option=LUA]
1279function(
1280    <t:integer> context,
1281    <t:integer> checks,
1282    ...
1283)
1284    -- no return values
1285end
1286\stoptyping
1287
1288\starttyping[option=LUA]
1289function initialize (
1290    <t:integer> context,
1291    <t:integer> checks,
1292    <t:integer> subpasses
1293)
1294    -- no return values
1295end
1296\stoptyping
1297
1298\starttyping[option=LUA]
1299function start (
1300    <t:integer> context,
1301    <t:integer> checks,
1302    <t:integer> pass,
1303    <t:integer> subpass,
1304    <t:integer> classes,
1305    <t:integer> decent
1306)
1307    -- no return values
1308end
1309\stoptyping
1310
1311\starttyping[option=LUA]
1312function stop (
1313    <t:integer> context,
1314    <t:integer> checks,
1315    <t:integer> demerits
1316)
1317    -- no return values
1318end
1319\stoptyping
1320
1321\starttyping[option=LUA]
1322function collect (
1323    <t:integer> context,
1324    <t:integer> checks
1325)
1326    -- no return values
1327end
1328\stoptyping
1329
1330\starttyping[option=LUA]
1331function line (
1332    <t:integer> context,
1333    <t:integer> checks,
1334    <t:integer> box,
1335    <t:integer> badness,
1336    <t:integer> overshoot,
1337    <t:integer> shrink,
1338    <t:integer> stretch,
1339    <t:integer> line,
1340    <t:integer> serial
1341)
1342    -- no return values
1343end
1344\stoptyping
1345
1346\starttyping[option=LUA]
1347function delete (
1348    <t:integer> context,
1349    <t:integer> checks,
1350    <t:integer> serial
1351)
1352    -- no return values
1353end
1354\stoptyping
1355
1356\starttyping[option=LUA]
1357function wrapup (
1358    <t:integer> context,
1359    <t:integer> checks,
1360    <t:integer> demerits,
1361    <t:integer> looseness
1362)
1363    -- no return values
1364end
1365\stoptyping
1366\starttyping[option=LUA]
1367function check (
1368    <t:integer> context,
1369    <t:integer> checks,
1370    <t:integer> pass,
1371    <t:integer> subpass,
1372    <t:integer> serial,
1373    <t:integer> prevserial,
1374    <t:integer> linenumber,
1375    <t:integer> nodetype,
1376    <t:integer> fitness,,
1377    <t:integer> demerits,
1378    <t:integer> classes,
1379    <t:integer> badness,
1380    <t:integer> demerits,
1381    <t:node>    breakpoint,
1382    <t:integer> short,
1383    <t:integer> glue,
1384    <t:integer> linewidth
1385)
1386    return <t:integer> demerits  -- optional
1387end
1388\stoptyping
1389
1390\starttyping[option=LUA]
1391function list (
1392    <t:integer> context,
1393    <t:integer> checks,
1394    <t:integer> serial
1395)
1396    -- no return values
1397end
1398\stoptyping
1399
1400Every one of these gets a \type {context} and \type {checks} passes. Possible
1401contexts are:
1402
1403\startfourrows
1404\getbuffer[engine:syntax:linebreakcontextcodes]
1405\stopfourrows
1406
1407The \type {checks} parameters is the value of \type {\linebreakchecks} which
1408makes it possible to plug in actions depending on that number. To give an idea if
1409what gets called, this is what you get when typesetting \type {tufte.tex}:
1410initialize, start, report, delete, delete, stop, start, report, report, delete,
1411report, report, report, delete, delete, report, report, report, delete, report,
1412delete, delete, report, report, report, delete, report, delete, delete, report,
1413report, delete, report, report, delete, delete, delete, report, delete, report,
1414delete, delete, report, report, report, delete, delete, report, delete, report,
1415report, delete, report, delete, delete, delete, report, report, delete, report,
1416report, delete, report, delete, report, delete, report, delete, delete, report,
1417report, report, report, delete, delete, delete, delete, delete, delete, delete,
1418delete, delete, report, stop, collect, list, list, list, list, list, list, list,
1419list, list, line, line, line, line, line, line, line, line, line, wrapup.
1420
1421\stopsubsection
1422
1423\startsubsection[title=show_build]
1424
1425You can trace (and even influence) the page builder with this callback. It comes in
1426several variants that are called during the process. Callbacks like these assume that
1427one knows what is going on in the engine.
1428
1429\starttyping[option=LUA]
1430function initialize (
1431    <t:integer> context
1432)
1433    -- no return values
1434end
1435\stoptyping
1436
1437\starttyping[option=LUA]
1438function step (
1439    <t:integer> context,
1440    <t:node>    current,
1441    <t:integer> pagegoal,
1442    <t:integer> pagetotal
1443)
1444    -- no return values
1445end
1446\stoptyping
1447
1448\starttyping[option=LUA]
1449function check (
1450    <t:integer> context,
1451    <t:node>    current,
1452    <t:boolean> moveon,
1453    <t:boolean> fireup,
1454    <t:integer> badness,
1455    <t:integer> costs,
1456    <t:integer> penalty
1457)
1458    return <t:boolean> moveon, <t:boolean> fireup
1459end
1460\stoptyping
1461
1462\starttyping[option=LUA]
1463function skip (
1464    <t:integer> context,
1465    <t:node>    current,
1466)
1467    -- no return values
1468end
1469\stoptyping
1470
1471\starttyping[option=LUA]
1472function move (
1473    <t:integer> context,
1474        <t:node>    current,
1475        <t:integer> lastheight,
1476        <t:integer> lastdepth,
1477        <t:integer> laststretch,
1478        <t:integer> lastshrink,
1479        <t:boolean> hasstretch
1480)
1481    -- no return values
1482end
1483\stoptyping
1484
1485\starttyping[option=LUA]
1486function fireup (
1487    <t:integer> context,
1488    <t:node> current
1489)
1490    -- no return values
1491end
1492\stoptyping
1493
1494\starttyping[option=LUA]
1495function wrapup (
1496    <t:integer> context
1497)
1498    -- no return values
1499end
1500\stoptyping
1501
1502\stopsubsection
1503
1504\startsubsection[title=show_whatsit]
1505
1506Because we only have a generic whatsit it is up to the macro package to provide
1507details when tracing them.
1508
1509\starttyping[option=LUA]
1510function (
1511    <t:node>    whatsit,
1512    <t:integer> indentation,
1513    <t:integer> tracinglevel,
1514    <t:integer> currentlevel,
1515    <t:integer> inputlevel
1516)
1517    -- no return value
1518end
1519\stoptyping
1520
1521Here \type {indentation} tells how many periods are to be typeset if you want to
1522be compatible with the rest of tracing. The \type {tracinglevel} indicates if the
1523current level and|/|or input level are shown cf. \type {\tracinglevels}. Of
1524course one is free to show whatever in whatever way suits the whatsit best.
1525
1526\stopsubsection
1527
1528\startsubsection[title=linebreak_quality]
1529
1530\starttyping[option=LUA]
1531function (
1532    <t:node>    par,
1533    <t:integer> id,
1534    <t:integer> pass,
1535    <t:integer> subpass,
1536    <t:integer> subpasses,
1537    <t:integer> state,
1538    <t:integer> overfull,
1539    <t:integer> underfull,
1540    <t:integer> verdict,
1541    <t:integer> classified,
1542    <t:integer> line
1543)
1544    return <t:node> result
1545end
1546\stoptyping
1547
1548\stopsubsection
1549
1550\startsubsection[title=show_loners]
1551
1552In spite of widow, club, broken and shaping penalties we can have single lines in the
1553result. When set, this callback replaces the output that normally \typ {\tracingloners}
1554produces.
1555
1556\starttyping[option=LUA]
1557function (
1558    <t:integer> options,
1559    <t:integer> penalty
1560)
1561    return <t:node> result
1562end
1563\stoptyping
1564
1565The options are those set on the encountered penalty:
1566
1567\startthreerows
1568\getbuffer[engine:syntax:penaltyoptioncodes]
1569\stopthreerows
1570
1571\stopsubsection
1572
1573\startsubsection[title=get_attribute]
1574
1575Because attributes are abstract pairs of indices and values the reported
1576properties makes not much sense and are very macro package (and user) dependent.
1577This callback permits more verbose reporting by the engine when tracing is
1578enabled.
1579
1580\starttyping[option=LUA]
1581function (
1582    <t:integer> index,
1583    <t:integer> value
1584)
1585    return <t:string>, <t:string>
1586end
1587\stoptyping
1588
1589\stopsubsection
1590
1591\startsubsection[title=get_noad_class]
1592
1593We have built|-|in math classes but there can also be user defined ones. This
1594callback can be used to report more meaningful strings instead of numbers when
1595tracing.
1596
1597\starttyping[option=LUA]
1598function (
1599    <t:integer> class
1600)
1601    return <t:string>
1602end
1603\stoptyping
1604
1605\stopsubsection
1606
1607\startsubsection[title=get_math_dictionary]
1608    todo
1609\stopsubsection
1610
1611\startsubsection[title=show_lua_call]
1612
1613When the engine traces something that involves a \LUA\ call it makes sense to report something
1614more meaningful than just that. This callback can be used provide a meaningful string (like the
1615name of a function).
1616
1617\starttyping[option=LUA]
1618function (
1619    <t:string>  name,
1620    <t:integer> index
1621)
1622    return <t:string>
1623end
1624\stoptyping
1625
1626\stopsubsection
1627
1628\startsubsection[title=trace_memory]
1629
1630When the engine starts all kind of memory is pre|-|allocated> depending on the
1631configuration more gets allocated when a category runs out of memory. The
1632\LUAMETATEX\ engine is more dynamic than \LUATEX. If this callback is set it will
1633get called as follows:
1634
1635\starttyping[option=LUA]
1636function (
1637    <t:string>  category,
1638    <t:boolean> success
1639)
1640    -- no return value
1641end
1642\stoptyping
1643
1644The boolean indicates if the allocation has been successful. One can best quit
1645the run when this one is \type {false} which the engine is likely to do that
1646anyway, be in in a less graceful way that you might like.
1647
1648\stopsubsection
1649
1650\startsubsection[title=paragraph_pass]
1651
1652{\em This callback is not yet stable.}
1653
1654\stopsubsection
1655
1656\stopsection
1657
1658\startsection[title=Math]
1659
1660\startsubsection[title=mlist_to_hlist]
1661
1662This callback replaces \LUATEX's math list to node list conversion algorithm.
1663
1664\starttyping[option=LUA]
1665function (
1666    <t:node>    head,
1667    <t:string>  display_type,
1668    <t:boolean> need_penalties
1669)
1670    return <t:node> newhead
1671end
1672\stoptyping
1673
1674The returned node is the head of the list that will be added to the vertical or
1675horizontal list, the string argument is either \quote {text} or \quote {display}
1676depending on the current math mode, the boolean argument is \type {true} if
1677penalties have to be inserted in this list, \type {false} otherwise.
1678
1679Setting this callback to \type {false} is bad, it will almost certainly result in
1680an endless loop.
1681
1682\stopsubsection
1683
1684\startsubsection[title=math_rule]
1685
1686In math rules are used for fractions, radicals and accents. In the case of
1687radicals rules mix with glyphs to build the symbol. In \CONTEXT\ we can enable an
1688alternate approach that uses glyphs instead of rules so that we can have more
1689consistent shapes, for instance with slopes or non square endings. This callback
1690takes care of that.
1691
1692\starttyping[option=LUA]
1693function (
1694    <t:integer> subtype,
1695    <t:integer> font,
1696    <t:integer> width,
1697    <t:integer> height,
1698    <t:node>    attributes
1699)
1700    return <t:node> rule
1701end
1702\stoptyping
1703
1704\stopsubsection
1705
1706\startsubsection[title=make_extensible]
1707
1708Like \typ {math_rule} this callback is used to construct nicer extensibles in \CONTEXT\
1709math support. It can optionally be followed by \typ {register_extensible}.
1710
1711\starttyping[option=LUA]
1712function (
1713    <t:node>    extensible,
1714    <t:integer> fnt,
1715    <t:integer> chr,
1716    <t:integer> size,
1717    <t:integer> width,
1718    <t:integer> height,
1719    <t:integer> depth,
1720    <t:integer> linewidth,
1721    <t:integer> axis,
1722    <t:integer> exheight,
1723    <t:integer> emwidth
1724)
1725    return <t:node> -- boxed extensible
1726end
1727\stoptyping
1728
1729\stopsubsection
1730
1731\startsubsection[title=register_extensible]
1732
1733This callback is a possible follow up on \typ {make_extensible} and it can be
1734used to share pre-build extensibles or package them otherwise (for instance as
1735\TYPETHREE\ glyph).
1736
1737\starttyping[option=LUA]
1738function (
1739    <t:integer> fnt,
1740    <t:integer> chr,
1741    <t:integer> size,
1742    <t:node>    attributes,
1743    <t:node>    extensible
1744)
1745    return <t:node> -- boxed
1746end
1747\stoptyping
1748
1749\stopsubsection
1750
1751\startsubsection[title=balance]
1752
1753This callback is comparable with the \type {line_break} callback. We use it for
1754tracing in \CONTEXT\ during development (as well as for documentation).
1755
1756\stopsubsection
1757
1758\startsubsection[title=balance_insert]
1759
1760This is callback kicks in every time an insert is seen when balancing.
1761
1762\starttyping[option=LUA]
1763function (
1764    <t:node>    current,
1765    <t:integer> callback,
1766    <t:integer> insert_index,
1767    <t:integer> insert_identifier
1768)
1769    -- no return value
1770end
1771\stoptyping
1772
1773\stopsubsection
1774
1775\startsubsection[title=balance_boundary]
1776
1777When balancing, this is callback kicks in every time a node resulting from \prm
1778{balanceboundary} is seen.
1779
1780\starttyping[option=LUA]
1781function (
1782    <t:integer> boundary_data,
1783    <t:integer> boundary_reserved,
1784    <t:integer> shape_identifier,
1785    <t:integer> shape_slot
1786)
1787    return
1788        <t:integer>, -- action
1789        <t:integer>, -- penalty
1790        <t:integer>  -- extra
1791end
1792\stoptyping
1793
1794What happens after the callback returns control to \TEX\ depends on the first
1795return value:
1796
1797\showenginevalues{getbalancecallbackvalues}
1798
1799This is an experimental feature. In due time there will be a bit more explanation
1800here.
1801
1802\stopsubsection
1803
1804\stopsection
1805
1806\stopdocument
1807
1808% timestamp october 2024, after running into Anna von Hausswolff's "All Thoughts
1809% Fly" live at Basilica di Santa Maria dei Servi 29.11.2021
1810