1 % \iffalse meta-comment
4 % The LaTeX3 Project and any individual authors listed elsewhere
7 % It may be distributed and/or modified under the conditions of
8 % the LaTeX Project Public License (LPPL), either version 1.3c of
9 % this license or (at your option) any later version. The latest
10 % version of this license is in the file:
12 % http://www.latex-project.org/lppl.txt
16 %<2ekernel>%%% From File: ltluatex.dtx
17 %<plain>\ifx\newluafunction\undefined\else\expandafter\endinput\fi
19 %<tex> \ProvidesFile\undefined\begingroup\def\ProvidesFile
20 %<tex> #1#2[#3]{\endgroup\immediate\write-1{File: #1 #3}}
22 %<plain>\ProvidesFile{ltluatex.tex}
24 \ProvidesFile{ltluatex.dtx}
29 %<plain> LuaTeX support for plain TeX (core)
32 \edef\etatcatcode{\the\catcode`\@}
36 \documentclass{ltxdoc}
37 \GetFileInfo{ltluatex.dtx}
39 \title{\filename\\(Lua\TeX{}-specific support)}
40 \author{David Carlisle and Joseph Wright\footnote{Significant portions
41 of the code here are adapted/simplified from the packages \textsf{luatex} and
42 \textsf{luatexbase} written by Heiko Oberdiek, \'{E}lie Roux,
43 Manuel P\'{e}gouri\'{e}-Gonnar and Philipp Gesang.}}
46 \setcounter{tocdepth}{2}
56 % Lua\TeX{} adds a number of engine-specific functions to \TeX{}. Several of
57 % these require set up that is best done in the kernel or need related support
58 % functions. This file provides \emph{basic} support for Lua\TeX{} at the
59 % \LaTeXe{} kernel level plus as a loadable file which can be used with
60 % plain \TeX{} and \LaTeX{}.
62 % This file contains code for both \TeX{} (to be stored as part of the format)
63 % and Lua (to be loaded at the start of each job). In the Lua code, the kernel
64 % uses the namespace |luatexbase|.
66 % The following |\count| registers are used here for register allocation:
68 % \item[\texttt{\string\e@alloc@attribute@count}] Attributes (default~258)
69 % \item[\texttt{\string\e@alloc@ccodetable@count}] Category code tables
71 % \item[\texttt{\string\e@alloc@luafunction@count}] Lua functions
73 % \item[\texttt{\string\e@alloc@whatsit@count}] User whatsits (default~261)
74 % \item[\texttt{\string\e@alloc@bytecode@count}] Lua bytecodes (default~262)
75 % \item[\texttt{\string\e@alloc@luachunk@count}] Lua chunks (default~263)
77 % (|\count 256| is used for |\newmarks| allocation and |\count 257|
78 % is used for\linebreak
79 % |\newXeTeXintercharclass| with Xe\TeX{}, with code defined in
80 % \texttt{ltfinal.dtx}).
81 % With any \LaTeXe{} kernel from 2015 onward these registers are part of
82 % the block in the extended area reserved by the kernel (prior to 2015 the
83 % \LaTeXe{} kernel did not provide any functionality for the extended
86 % \section{Core \TeX{} functionality}
88 % The commands defined here are defined for
89 % possible inclusion in a future \LaTeX{} format, however also extracted
90 % to the file |ltluatex.tex| which may be used with older \LaTeX\
91 % formats, and with plain \TeX.
94 % \DescribeMacro{\newattribute}
95 % |\newattribute{|\meta{attribute}|}|\\
96 % Defines a named \cs{attribute}, indexed from~$1$
97 % (\emph{i.e.}~|\attribute0| is never defined). Attributes initially
98 % have the marker value |-"7FFFFFFF| (`unset') set by the engine.
101 % \DescribeMacro{\newcatcodetable}
102 % |\newcatcodetable{|\meta{catcodetable}|}|\\
103 % Defines a named \cs{catcodetable}, indexed from~$1$
104 % (|\catcodetable0| is never assigned). A new catcode table will be
105 % populated with exactly those values assigned by Ini\TeX{} (as described
106 % in the Lua\TeX{} manual).
109 % \DescribeMacro{\newluafunction}
110 % |\newluafunction{|\meta{function}|}|\\
111 % Defines a named \cs{luafunction}, indexed from~$1$. (Lua indexes
112 % tables from $1$ so |\luafunction0| is not available).
115 % \DescribeMacro{\newwhatsit}
116 % |\newwhatsit{|\meta{whatsit}|}|\\
117 % Defines a custom \cs{whatsit}, indexed from~$1$.
120 % \DescribeMacro{\newluabytecode}
121 % |\newluabytecode{|\meta{bytecode}|}|\\
122 % Allocates a number for Lua bytecode register, indexed from~$1$.
125 % \DescribeMacro{\newluachunkname}
126 % |newluachunkname{|\meta{chunkname}|}|\\
127 % Allocates a number for Lua chunk register, indexed from~$1$.
128 % Also enters the name of the regiser (without backslash) into the
129 % \verb|lua.name| table to be used in stack traces.
132 % \DescribeMacro{\catcodetable@initex}
133 % \DescribeMacro{\catcodetable@string}
134 % \DescribeMacro{\catcodetable@latex}
135 % \DescribeMacro{\catcodetable@atletter}
136 % Predefined category code tables with the obvious assignments. Note
137 % that the |latex| and |atletter| tables set the full Unicode range
138 % to the codes predefined by the kernel.
141 % \DescribeMacro{\setattribute}
142 % \DescribeMacro{\unsetattribute}
143 % |\setattribute{|\meta{attribute}|}{|\meta{value}|}|\\
144 % |\unsetattribute{|\meta{attribute}|}|\\
145 % Set and unset attributes in a manner analogous to |\setlength|. Note that
146 % attributes take a marker value when unset so this operation is distinct
147 % from setting the value to zero.
149 % \section{Plain \TeX\ interface}
151 % The \textsf{ltluatex} interface may be used with plain \TeX\ using
152 % |\input{ltluatex}|. This inputs |ltluatex.tex| which inputs
153 % |etex.src| (or |etex.sty| if used with \LaTeX)
154 % if it is not already input, and then defines some internal commands to
155 % allow the \textsf{ltluatex} interface to be defined.
157 % The \textsf{luatexbase} package interface may also be used in plain \TeX,
158 % as before, by inputting the package |\input luatexbase.sty|. The new
159 % version of \textsf{luatexbase} is based on this \textsf{ltluatex}
160 % code but implements a compatibility layer providing the interface
161 % of the original package.
163 % \section{Lua functionality}
167 % \begingroup\lccode`~=`_
168 % \lowercase{\endgroup\let~}_
171 % \subsection{Allocators in Lua}
173 % \DescribeMacro{new\_attribute}
174 % |luatexbase.new_attribute(|\meta{attribute}|)|\\
175 % Returns an allocation number for the \meta{attribute}, indexed from~$1$.
176 % The attribute will be initialised with the marker value |-"7FFFFFFF|
177 % (`unset'). The attribute allocation sequence is shared with the \TeX{}
178 % code but this function does \emph{not} define a token using
180 % The attribute name is recorded in the |attributes| table. A
181 % metatable is provided so that the table syntax can be used
182 % consistently for attributes declared in \TeX\ or Lua.
185 % \DescribeMacro{new\_whatsit}
186 % |luatexbase.new_whatsit(|\meta{whatsit}|)|\\
187 % Returns an allocation number for the custom \meta{whatsit}, indexed from~$1$.
190 % \DescribeMacro{new\_bytecode}
191 % |luatexbase.new_bytecode(|\meta{bytecode}|)|\\
192 % Returns an allocation number for a bytecode register, indexed from~$1$.
193 % The optional \meta{name} argument is just used for logging.
196 % \DescribeMacro{new\_chunkname}
197 % |luatexbase.new_chunkname(|\meta{chunkname}|)|\\
198 % Returns an allocation number for a Lua chunk name for use with
199 % |\directlua| and |\latelua|, indexed from~$1$.
200 % The number is returned and also \meta{name} argument is added to the
201 % |lua.name| array at that index.
204 % \subsection{Lua access to \TeX{} register numbers}
206 % \DescribeMacro{registernumber}
207 % |luatexbase.registernumer(|\meta{name}|)|\\
208 % Sometimes (notably in the case of Lua attributes) it is necessary to
209 % access a register \emph{by number} that has been allocated by \TeX{}.
210 % This package provides a function to look up the relevant number
211 % using Lua\TeX{}'s internal tables. After for example
212 % |\newattribute\myattrib|, |\myattrib| would be defined by (say)
213 % |\myattrib=\attribute15|. |luatexbase.registernumer("myattrib")|
214 % would then return the register number, $15$ in this case. If the string passed
215 % as argument does not correspond to a token defined by |\attributedef|,
216 % |\countdef| or similar commands, the Lua value |false| is returned.
218 % As an example, consider the input:
220 % \newcommand\test[1]{%
221 % \typeout{#1: \expandafter\meaning\csname#1\endcsname^^J
222 % \space\space\space\space
223 % \directlua{tex.write(luatexbase.registernumber("#1") or "bad input")}%
226 % \test{undefinedrubbish}
241 % \attrbutedef\myattr=12
247 % If the demonstration code is processed with Lua\LaTeX{} then the following
248 % would be produced in the log and terminal output.
250 % undefinedrubbish: \relax
256 % @MM: \mathchar"4E20
258 % @tempdima: \dimen14
260 % @tempdimb: \dimen15
266 % myattr: \attribute12
270 % Notice how undefined commands, or commands unrelated to registers
271 % do not produce an error, just return |false| and so print
272 % |bad input| here. Note also that commands defined by |\newbox| work and
273 % return the number of the box register even though the actual command
274 % holding this number is a |\chardef| defined token (there is no
277 % \subsection{Module utilities}
279 % \DescribeMacro{provides\_module}
280 % |luatexbase.provides_module(|\meta{info}|)|\\
281 % This function is used by modules to identify themselves; the |info| should be
282 % a table containing information about the module. The required field
283 % |name| must contain the name of the module. It is recommended to provide a
284 % field |date| in the usual \LaTeX{} format |yyyy/mm/dd|. Optional fields
285 % |version| (a string) and |description| may be used if present. This
286 % information will be recorded in the log. Other fields are ignored.
289 % \DescribeMacro{module\_info}
290 % \DescribeMacro{module\_warning}
291 % \DescribeMacro{module\_error}
292 % |luatexbase.module_info(|\meta{module}, \meta{text}|)|\\
293 % |luatexbase.module_warning(|\meta{module}, \meta{text}|)|\\
294 % |luatexbase.module_error(|\meta{module}, \meta{text}|)|\\
295 % These functions are similar to \LaTeX{}'s |\PackageError|, |\PackageWarning|
296 % and |\PackageInfo| in the way they format the output. No automatic line
297 % breaking is done, you may still use |\n| as usual for that, and the name of
298 % the package will be prepended to each output line.
300 % Note that |luatexbase.module_error| raises an actual Lua error with |error()|,
301 % which currently means a call stack will be dumped. While this may not
302 % look pretty, at least it provides useful information for tracking the
305 % \subsection{Callback management}
308 % \DescribeMacro{add\_to\_callback}
309 % |luatexbase.add_to_callback(|^^A
310 % \meta{callback}, \meta{function}, \meta{description}|)|
311 % Registers the \meta{function} into the \meta{callback} with a textual
312 % \meta{description} of the function. Functions are inserted into the callback
313 % in the order loaded.
316 % \DescribeMacro{remove\_from\_callback}
317 % |luatexbase.remove_from_callback(|\meta{callback}, \meta{description}|)|
318 % Removes the callback function with \meta{description} from the \meta{callback}.
319 % The removed function and its description
320 % are returned as the results of this function.
323 % \DescribeMacro{in\_callback}
324 % |luatexbase.in_callback(|\meta{callback}, \meta{description}|)|
325 % Checks if the \meta{description} matches one of the functions added
326 % to the list for the \meta{callback}, returning a boolean value.
329 % \DescribeMacro{disable\_callback}
330 % |luatexbase.disable_callback(|\meta{callback}|)|
331 % Sets the \meta{callback} to \texttt{false} as described in the Lua\TeX{}
332 % manual for the underlying \texttt{callback.register} built-in. Callbacks
333 % will only be set to false (and thus be skipped entirely) if there are
334 % no functions registered using the callback.
337 % \DescribeMacro{callback\_descriptions}
338 % A list of the descriptions of functions registered to the specified
339 % callback is returned. |{}| is returned if there are no functions registered.
342 % \DescribeMacro{create\_callback}
343 % |luatexbase.create_callback(|\meta{name},meta{type},\meta{default}|)|
344 % Defines a user defined callback. The last argument is a default
345 % function or |false|.
348 % \DescribeMacro{call\_callback}
349 % |luatexbase.call_callback(|\meta{name},\ldots|)|
350 % Calls a user defined callback with the supplied arguments.
356 % \section{Implementation}
359 %<*2ekernel|tex|latexrelease>
360 %<2ekernel|latexrelease>\ifx\directlua\@undefined\else
364 % \changes{v1.0j}{2015/12/02}{Remove nonlocal iteration variables (PHG)}
365 % \changes{v1.0j}{2015/12/02}{Assorted typos fixed (PHG)}
366 % \changes{v1.0j}{2015/12/02}{Remove unreachable code after calls to error() (PHG)}
367 % \subsection{Minimum Lua\TeX{} version}
369 % Lua\TeX{} has changed a lot over time. In the kernel support for ancient
370 % versions is not provided: trying to build a format with a very old binary
371 % therefore gives some information in the log and loading stops. The cut-off
372 % selected here relates to the tree-searching behaviour of |require()|:
373 % from version~0.60, Lua\TeX{} will correctly find Lua files in the |texmf|
374 % tree without `help'.
376 %<latexrelease>\IncludeInRelease{2015/10/01}
377 %<latexrelease> {\newluafunction}{LuaTeX}%
378 \ifnum\luatexversion<60 %
379 \wlog{***************************************************}
380 \wlog{* LuaTeX version too old for ltluatex support *}
381 \wlog{***************************************************}
382 \expandafter\endinput
386 % \subsection{Older \LaTeX{}/Plain \TeX\ setup}
392 % Older \LaTeX{} formats don't have the primitives with `native' names:
393 % sort that out. If they already exist this will still be safe.
395 \directlua{tex.enableprimitives("",tex.extraprimitives("luatex"))}
399 \ifx\e@alloc\@undefined
402 % In pre-2014 \LaTeX{}, or plain \TeX{}, load |etex.{sty,src}|.
404 \ifx\documentclass\@undefined
405 \ifx\loccount\@undefined
409 \outer\expandafter\def\csname newfam\endcsname
410 {\alloc@8\fam\chardef\et@xmaxfam}
412 \RequirePackage{etex}
413 \expandafter\def\csname newfam\endcsname
414 {\alloc@8\fam\chardef\et@xmaxfam}
415 \expandafter\let\expandafter\new@mathgroup\csname newfam\endcsname
419 % \subsubsection{Fixes to \texttt{etex.src}/\texttt{etex.sty}}
421 % These could and probably should be made directly in an
422 % update to |etex.src| which already has some Lua\TeX-specific
423 % code, but does not define the correct range for Lua\TeX.
426 % 2015-07-13 higher range in luatex
427 \edef \et@xmaxregs {\ifx\directlua\@undefined 32768\else 65536\fi}
428 % luatex/xetex also allow more math fam
429 \edef \et@xmaxfam {\ifx\Umathchar\@undefined\sixt@@n\else\@cclvi\fi}
433 \count 270=\et@xmaxregs % locally allocates \count registers
434 \count 271=\et@xmaxregs % ditto for \dimen registers
435 \count 272=\et@xmaxregs % ditto for \skip registers
436 \count 273=\et@xmaxregs % ditto for \muskip registers
437 \count 274=\et@xmaxregs % ditto for \box registers
438 \count 275=\et@xmaxregs % ditto for \toks registers
439 \count 276=\et@xmaxregs % ditto for \marks classes
442 % and 256 or 16 fam. (Done above due to plain/\LaTeX\ differences in
443 % \textsf{ltluatex}.)
445 % \outer\def\newfam{\alloc@8\fam\chardef\et@xmaxfam}
448 % End of proposed changes to \texttt{etex.src}
450 % \subsubsection{luatex specific settings}
452 % Switch to global cf |luatex.sty| to leave room for inserts
453 % not really needed for luatex but possibly most compatible
456 \expandafter\let\csname newcount\expandafter\expandafter\endcsname
457 \csname globcount\endcsname
458 \expandafter\let\csname newdimen\expandafter\expandafter\endcsname
459 \csname globdimen\endcsname
460 \expandafter\let\csname newskip\expandafter\expandafter\endcsname
461 \csname globskip\endcsname
462 \expandafter\let\csname newbox\expandafter\expandafter\endcsname
463 \csname globbox\endcsname
466 % Define|\e@alloc| as in latex (the existing macros in |etex.src|
467 % hard to extend to further register types as they assume specific
468 % 26x and 27x count range. For compatibility the existing register
469 % allocation is not changed.
472 \chardef\e@alloc@top=65535
473 \let\e@alloc@chardef\chardef
477 \def\e@alloc#1#2#3#4#5#6{%
478 \global\advance#3\@ne
479 \e@ch@ck{#3}{#4}{#5}#1%
480 \allocationnumber#3\relax
481 \global#2#6\allocationnumber
482 \wlog{\string#6=\string#1\the\allocationnumber}}%
486 \gdef\e@ch@ck#1#2#3#4{%
490 \ifx\count#4\advance#1 10 \fi
494 \errmessage{No room for a new \string#4}%
499 % Two simple \LaTeX\ macros used in |ltlatex.sty|.
501 \long\def\@gobble#1{}
502 \long\def\@firstofone#1{#1}
506 % Fix up allocations not to clash with |etex.src|.
510 \expandafter\csname newcount\endcsname\e@alloc@attribute@count
511 \expandafter\csname newcount\endcsname\e@alloc@ccodetable@count
512 \expandafter\csname newcount\endcsname\e@alloc@luafunction@count
513 \expandafter\csname newcount\endcsname\e@alloc@whatsit@count
514 \expandafter\csname newcount\endcsname\e@alloc@bytecode@count
515 \expandafter\csname newcount\endcsname\e@alloc@luachunk@count
518 % End of conditional setup for plain \TeX\ / old \LaTeX.
525 % \subsection{Attributes}
527 % \begin{macro}{\newattribute}
528 % \changes{v1.0a}{2015/09/24}{Macro added}
529 % As is generally the case for the Lua\TeX{} registers we start here
530 % from~$1$. Notably, some code assumes that |\attribute0| is never used so
531 % this is important in this case.
533 \ifx\e@alloc@attribute@count\@undefined
534 \countdef\e@alloc@attribute@count=258
536 \def\newattribute#1{%
537 \e@alloc\attribute\attributedef
538 \e@alloc@attribute@count\m@ne\e@alloc@top#1%
540 \e@alloc@attribute@count=\z@
544 % \begin{macro}{\setattribute}
545 % \begin{macro}{\unsetattribute}
548 \def\setattribute#1#2{#1=\numexpr#2\relax}
549 \def\unsetattribute#1{#1=-"7FFFFFFF\relax}
554 % \subsection{Category code tables}
556 % \begin{macro}{\newcatcodetable}
557 % \changes{v1.0a}{2015/09/24}{Macro added}
558 % Category code tables are allocated with a limit half of that used by Lua\TeX{}
559 % for everything else. At the end of allocation there needs to be an
560 % initialisation step. Table~$0$ is already taken (it's the global one for
561 % current use) so the allocation starts at~$1$.
563 \ifx\e@alloc@ccodetable@count\@undefined
564 \countdef\e@alloc@ccodetable@count=259
566 \def\newcatcodetable#1{%
567 \e@alloc\catcodetable\chardef
568 \e@alloc@ccodetable@count\m@ne{"8000}#1%
569 \initcatcodetable\allocationnumber
571 \e@alloc@ccodetable@count=\z@
575 % \changes{v1.0l}{2015/12/18}{Load Unicode data from source}
576 % \begin{macro}{\catcodetable@initex}
577 % \changes{v1.0a}{2015/09/24}{Macro added}
578 % \begin{macro}{\catcodetable@string}
579 % \changes{v1.0a}{2015/09/24}{Macro added}
580 % \begin{macro}{\catcodetable@latex}
581 % \changes{v1.0a}{2015/09/24}{Macro added}
582 % \begin{macro}{\catcodetable@atletter}
583 % \changes{v1.0a}{2015/09/24}{Macro added}
584 % Save a small set of standard tables. The Unicode data is read
585 % here in using a parser simplified from that in |load-unicode-data|:
586 % only the nature of letters needs to be detected.
588 \newcatcodetable\catcodetable@initex
589 \newcatcodetable\catcodetable@string
591 \def\setrangecatcode#1#2#3{%
595 \expandafter\@firstofone
599 \expandafter\setrangecatcode\expandafter
600 {\number\numexpr#1 + 1\relax}{#2}{#3}
604 \catcodetable\catcodetable@initex
608 \setrangecatcode{65}{90}{12}%
609 \setrangecatcode{97}{122}{12}%
612 \savecatcodetable\catcodetable@string
615 \newcatcodetable\catcodetable@latex
616 \newcatcodetable\catcodetable@atletter
618 \def\parseunicodedataI#1;#2;#3;#4\relax{%
619 \parseunicodedataII#1;#3;#2 First>\relax
621 \def\parseunicodedataII#1;#2;#3 First>#4\relax{%
623 \expandafter\parseunicodedataIII
625 \expandafter\parseunicodedataIV
629 \def\parseunicodedataIII#1#2#3\relax{%
637 \def\parseunicodedataIV#1#2#3\relax{%
638 \read\unicoderead to \unicodedataline
641 \expandafter\parseunicodedataV\unicodedataline\relax
644 \def\parseunicodedataV#1;#2\relax{%
646 \unless\ifnum\count0>"#1 %
648 \advance\count0 by 1 %
651 \def\storedpar{\par}%
652 \chardef\unicoderead=\numexpr\count16 + 1\relax
653 \openin\unicoderead=UnicodeData.txt %
654 \loop\unless\ifeof\unicoderead %
655 \read\unicoderead to \unicodedataline
656 \unless\ifx\unicodedataline\storedpar
657 \expandafter\parseunicodedataI\unicodedataline\relax
663 \savecatcodetable\catcodetable@latex
665 \savecatcodetable\catcodetable@atletter
674 % \subsection{Named Lua functions}
676 % \begin{macro}{\newluafunction}
677 % \changes{v1.0a}{2015/09/24}{Macro added}
678 % Much the same story for allocating Lua\TeX{} functions except here they are
679 % just numbers so they are allocated in the same way as boxes.
680 % Lua indexes from~$1$ so once again slot~$0$ is skipped.
682 \ifx\e@alloc@luafunction@count\@undefined
683 \countdef\e@alloc@luafunction@count=260
685 \def\newluafunction{%
686 \e@alloc\luafunction\e@alloc@chardef
687 \e@alloc@luafunction@count\m@ne\e@alloc@top
689 \e@alloc@luafunction@count=\z@
693 % \subsection{Custom whatsits}
695 % \begin{macro}{\newwhatsit}
696 % \changes{v1.0a}{2015/09/24}{Macro added}
697 % These are only settable from Lua but for consistency are definable
700 \ifx\e@alloc@whatsit@count\@undefined
701 \countdef\e@alloc@whatsit@count=261
704 \e@alloc\whatsit\e@alloc@chardef
705 \e@alloc@whatsit@count\m@ne\e@alloc@top#1%
707 \e@alloc@whatsit@count=\z@
711 % \subsection{Lua bytecode registers}
713 % \begin{macro}{\newluabytecode}
714 % \changes{v1.0a}{2015/09/24}{Macro added}
715 % These are only settable from Lua but for consistency are definable
718 \ifx\e@alloc@bytecode@count\@undefined
719 \countdef\e@alloc@bytecode@count=262
721 \def\newluabytecode#1{%
722 \e@alloc\luabytecode\e@alloc@chardef
723 \e@alloc@bytecode@count\m@ne\e@alloc@top#1%
725 \e@alloc@bytecode@count=\z@
729 % \subsection{Lua chunk registers}
731 % \begin{macro}{\newluachunkname}
732 % \changes{v1.0a}{2015/09/24}{Macro added}
733 % As for bytecode registers, but in addition we need to add a string
734 % to the \verb|lua.name| table to use in stack tracing. We use the
735 % name of the command passed to the allocator, with no backslash.
737 \ifx\e@alloc@luachunk@count\@undefined
738 \countdef\e@alloc@luachunk@count=263
740 \def\newluachunkname#1{%
741 \e@alloc\luachunk\e@alloc@chardef
742 \e@alloc@luachunk@count\m@ne\e@alloc@top#1%
744 \directlua{lua.name[\the\allocationnumber]="\string#1"}}%
746 \e@alloc@luachunk@count=\z@
750 % \subsection{Lua loader}
752 % Load the Lua code at the start of every job.
753 % For the conversion of \TeX{} into numbers at the Lua side we need some
754 % known registers: for convenience we use a set of systematic names, which
755 % means using a group around the Lua loader.
757 %<2ekernel>\everyjob\expandafter{%
758 %<2ekernel> \the\everyjob
760 \attributedef\attributezero=0 %
761 \chardef \charzero =0 %
763 % Note name change required on older luatex, for hash table access.
765 \countdef \CountZero =0 %
766 \dimendef \dimenzero =0 %
767 \mathchardef \mathcharzero =0 %
768 \muskipdef \muskipzero =0 %
769 \skipdef \skipzero =0 %
770 \toksdef \tokszero =0 %
771 \directlua{require("ltluatex")}
774 %<latexrelease>\EndIncludeInRelease
778 % \changes{v1.0b}{2015/10/02}{Fix backing out of \TeX{} code}
779 % \changes{v1.0c}{2015/10/02}{Allow backing out of Lua code}
780 %<latexrelease>\IncludeInRelease{0000/00/00}
781 %<latexrelease> {\newluafunction}{LuaTeX}%
782 %<latexrelease>\let\e@alloc@attribute@count\@undefined
783 %<latexrelease>\let\newattribute\@undefined
784 %<latexrelease>\let\setattribute\@undefined
785 %<latexrelease>\let\unsetattribute\@undefined
786 %<latexrelease>\let\e@alloc@ccodetable@count\@undefined
787 %<latexrelease>\let\newcatcodetable\@undefined
788 %<latexrelease>\let\catcodetable@initex\@undefined
789 %<latexrelease>\let\catcodetable@string\@undefined
790 %<latexrelease>\let\catcodetable@latex\@undefined
791 %<latexrelease>\let\catcodetable@atletter\@undefined
792 %<latexrelease>\let\e@alloc@luafunction@count\@undefined
793 %<latexrelease>\let\newluafunction\@undefined
794 %<latexrelease>\let\e@alloc@luafunction@count\@undefined
795 %<latexrelease>\let\newwhatsit\@undefined
796 %<latexrelease>\let\e@alloc@whatsit@count\@undefined
797 %<latexrelease>\let\newluabytecode\@undefined
798 %<latexrelease>\let\e@alloc@bytecode@count\@undefined
799 %<latexrelease>\let\newluachunkname\@undefined
800 %<latexrelease>\let\e@alloc@luachunk@count\@undefined
801 %<latexrelease>\directlua{luatexbase.uninstall()}
802 %<latexrelease>\EndIncludeInRelease
806 %<2ekernel|latexrelease>\fi
807 %</2ekernel|tex|latexrelease>
810 % \subsection{Lua module preliminaries}
814 % \begingroup\lccode`~=`_
815 % \lowercase{\endgroup\let~}_
822 % Some set up for the Lua module which is needed for all of the Lua
823 % functionality added here.
825 % \begin{macro}{luatexbase}
826 % \changes{v1.0a}{2015/09/24}{Table added}
827 % Set up the table for the returned functions. This is used to expose
828 % all of the public functions.
830 luatexbase = luatexbase or { }
831 local luatexbase = luatexbase
835 % Some Lua best practice: use local versions of functions where possible.
837 local string_gsub = string.gsub
838 local tex_count = tex.count
839 local tex_setattribute = tex.setattribute
840 local tex_setcount = tex.setcount
841 local texio_write_nl = texio.write_nl
843 % \changes{v1.0i}{2015/11/29}{Declare this as local before used in the module error definitions (PHG)}
845 local luatexbase_warning
846 local luatexbase_error
849 % \subsection{Lua module utilities}
851 % \subsubsection{Module tracking}
853 % \begin{macro}{modules}
854 % \changes{v1.0a}{2015/09/24}{Function modified}
855 % To allow tracking of module usage, a structure is provided to store
856 % information and to return it.
858 local modules = modules or { }
862 % \begin{macro}{provides\_module}
863 % \changes{v1.0a}{2015/09/24}{Function added}
864 % \changes{v1.0f}{2015/10/03}{use luatexbase\_log}
865 % Local function to write to the log.
867 local function luatexbase_log(text)
868 texio_write_nl("log", text)
872 % Modelled on |\ProvidesPackage|, we store much the same information but
873 % with a little more structure.
875 local function provides_module(info)
876 if not (info and info.name) then
877 luatexbase_error("Missing module name for provides_module")
879 local function spaced(text)
880 return text and (" " .. text) or ""
883 "Lua module: " .. info.name
885 .. spaced(info.version)
886 .. spaced(info.description)
888 modules[info.name] = info
890 luatexbase.provides_module = provides_module
894 % \subsubsection{Module messages}
896 % There are various warnings and errors that need to be given. For warnings
897 % we can get exactly the same formatting as from \TeX{}. For errors we have to
898 % make some changes. Here we give the text of the error in the \LaTeX{} format
899 % then force an error from Lua to halt the run. Splitting the message text is
900 % done using |\n| which takes the place of |\MessageBreak|.
902 % First an auxiliary for the formatting: this measures up the message
903 % leader so we always get the correct indent.
904 % \changes{v1.0j}{2015/12/02}{Declaration/use of first\_head fixed (PHG)}
906 local function msg_format(mod, msg_type, text)
910 if mod == "LaTeX" then
911 cont = string_gsub(leader, ".", " ")
912 first_head = leader .. "LaTeX: "
914 first_head = leader .. "Module " .. msg_type
915 cont = "(" .. mod .. ")"
916 .. string_gsub(first_head, ".", " ")
917 first_head = leader .. "Module " .. mod .. " " .. msg_type .. ":"
919 if msg_type == "Error" then
920 first_head = "\n" .. first_head
922 if string.sub(text,-1) ~= "\n" then
925 return first_head .. " "
929 .. tex.inputlineno, "\n", "\n" .. cont .. " "
935 % \begin{macro}{module\_info}
936 % \changes{v1.0a}{2015/09/24}{Function added}
937 % \begin{macro}{module\_warning}
938 % \changes{v1.0a}{2015/09/24}{Function added}
939 % \begin{macro}{module\_error}
940 % \changes{v1.0a}{2015/09/24}{Function added}
943 local function module_info(mod, text)
944 texio_write_nl("log", msg_format(mod, "Info", text))
946 luatexbase.module_info = module_info
947 local function module_warning(mod, text)
948 texio_write_nl("term and log",msg_format(mod, "Warning", text))
950 luatexbase.module_warning = module_warning
951 local function module_error(mod, text)
952 error(msg_format(mod, "Error", text))
954 luatexbase.module_error = module_error
960 % Dedicated versions for the rest of the code here.
962 function luatexbase_warning(text)
963 module_warning("luatexbase", text)
965 function luatexbase_error(text)
966 module_error("luatexbase", text)
971 % \subsection{Accessing register numbers from Lua}
973 % \changes{v1.0g}{2015/11/14}{Track Lua\TeX{} changes for
974 % \texttt{(new)token.create}}
975 % Collect up the data from the \TeX{} level into a Lua table: from
976 % version~0.80, Lua\TeX{} makes that easy.
977 % \changes{v1.0j}{2015/12/02}{Adjust hashtokens to store the result of tex.hashtokens()), not the function (PHG)}
979 local luaregisterbasetable = { }
980 local registermap = {
981 attributezero = "assign_attr" ,
982 charzero = "char_given" ,
983 CountZero = "assign_int" ,
984 dimenzero = "assign_dimen" ,
985 mathcharzero = "math_given" ,
986 muskipzero = "assign_mu_skip" ,
987 skipzero = "assign_skip" ,
988 tokszero = "assign_toks" ,
991 if tex.luatexversion > 81 then
992 createtoken = token.create
993 elseif tex.luatexversion > 79 then
994 createtoken = newtoken.create
996 local hashtokens = tex.hashtokens()
997 local luatexversion = tex.luatexversion
998 for i,j in pairs (registermap) do
999 if luatexversion < 80 then
1000 luaregisterbasetable[hashtokens[i][1]] =
1003 luaregisterbasetable[j] = createtoken(i).mode
1008 % \begin{macro}{registernumber}
1009 % Working out the correct return value can be done in two ways. For older
1010 % Lua\TeX{} releases it has to be extracted from the |hashtokens|. On the
1011 % other hand, newer Lua\TeX{}'s have |newtoken|, and whilst |.mode| isn't
1012 % currently documented, Hans Hagen pointed to this approach so we should be
1015 local registernumber
1016 if luatexversion < 80 then
1017 function registernumber(name)
1018 local nt = hashtokens[name]
1019 if(nt and luaregisterbasetable[nt[1]]) then
1020 return nt[2] - luaregisterbasetable[nt[1]]
1026 function registernumber(name)
1027 local nt = createtoken(name)
1028 if(luaregisterbasetable[nt.cmdname]) then
1029 return nt.mode - luaregisterbasetable[nt.cmdname]
1035 luatexbase.registernumber = registernumber
1039 % \subsection{Attribute allocation}
1041 % \begin{macro}{new\_attribute}
1042 % \changes{v1.0a}{2015/09/24}{Function added}
1043 % As attributes are used for Lua manipulations its useful to be able
1044 % to assign from this end.
1046 local attributes=setmetatable(
1049 __index = function(t,key)
1050 return registernumber(key) or nil
1053 luatexbase.attributes=attributes
1057 local function new_attribute(name)
1058 tex_setcount("global", "e@alloc@attribute@count",
1059 tex_count["e@alloc@attribute@count"] + 1)
1060 if tex_count["e@alloc@attribute@count"] > 65534 then
1061 luatexbase_error("No room for a new \\attribute")
1063 attributes[name]= tex_count["e@alloc@attribute@count"]
1064 luatexbase_log("Lua-only attribute " .. name .. " = " ..
1065 tex_count["e@alloc@attribute@count"])
1066 return tex_count["e@alloc@attribute@count"]
1068 luatexbase.new_attribute = new_attribute
1072 % \subsection{Custom whatsit allocation}
1074 % \begin{macro}{new\_whatsit}
1075 % Much the same as for attribute allocation in Lua.
1077 local function new_whatsit(name)
1078 tex_setcount("global", "e@alloc@whatsit@count",
1079 tex_count["e@alloc@whatsit@count"] + 1)
1080 if tex_count["e@alloc@whatsit@count"] > 65534 then
1081 luatexbase_error("No room for a new custom whatsit")
1083 luatexbase_log("Custom whatsit " .. (name or "") .. " = " ..
1084 tex_count["e@alloc@whatsit@count"])
1085 return tex_count["e@alloc@whatsit@count"]
1087 luatexbase.new_whatsit = new_whatsit
1091 % \subsection{Bytecode register allocation}
1093 % \begin{macro}{new\_bytecode}
1094 % Much the same as for attribute allocation in Lua.
1095 % The optional \meta{name} argument is used in the log if given.
1097 local function new_bytecode(name)
1098 tex_setcount("global", "e@alloc@bytecode@count",
1099 tex_count["e@alloc@bytecode@count"] + 1)
1100 if tex_count["e@alloc@bytecode@count"] > 65534 then
1101 luatexbase_error("No room for a new bytecode register")
1103 luatexbase_log("Lua bytecode " .. (name or "") .. " = " ..
1104 tex_count["e@alloc@bytecode@count"])
1105 return tex_count["e@alloc@bytecode@count"]
1107 luatexbase.new_bytecode = new_bytecode
1111 % \subsection{Lua chunk name allocation}
1113 % \begin{macro}{new\_chunkname}
1114 % As for bytecode registers but also store the name in the
1117 local function new_chunkname(name)
1118 tex_setcount("global", "e@alloc@luachunk@count",
1119 tex_count["e@alloc@luachunk@count"] + 1)
1120 local chunkname_count = tex_count["e@alloc@luachunk@count"]
1121 chunkname_count = chunkname_count + 1
1122 if chunkname_count > 65534 then
1123 luatexbase_error("No room for a new chunkname")
1125 lua.name[chunkname_count]=name
1126 luatexbase_log("Lua chunkname " .. (name or "") .. " = " ..
1127 chunkname_count .. "\n")
1128 return chunkname_count
1130 luatexbase.new_chunkname = new_chunkname
1134 % \subsection{Lua callback management}
1136 % The native mechanism for callbacks in Lua\TeX\ allows only one per function.
1137 % That is extremely restrictive and so a mechanism is needed to add and
1138 % remove callbacks from the appropriate hooks.
1140 % \subsubsection{Housekeeping}
1142 % The main table: keys are callback names, and values are the associated lists
1143 % of functions. More precisely, the entries in the list are tables holding the
1144 % actual function as |func| and the identifying description as |description|.
1145 % Only callbacks with a non-empty list of functions have an entry in this
1148 local callbacklist = callbacklist or { }
1151 % Numerical codes for callback types, and name-to-value association (the
1152 % table keys are strings, the values are numbers).
1154 local list, data, exclusive, simple = 1, 2, 3, 4
1158 exclusive = exclusive,
1163 % Now, list all predefined callbacks with their current type, based on the
1164 % Lua\TeX{} manual version~0.80. A full list of the currently-available
1165 % callbacks can be obtained using
1168 % for i,_ in pairs(callback.list()) do
1169 % texio.write_nl("- " .. i)
1174 % in plain Lua\TeX{}. (Some undocumented callbacks are omitted as they are
1177 local callbacktypes = callbacktypes or {
1179 % Section 4.1.1: file discovery callbacks.
1181 find_read_file = exclusive,
1182 find_write_file = exclusive,
1183 find_font_file = data,
1184 find_output_file = data,
1185 find_format_file = data,
1186 find_vf_file = data,
1187 find_map_file = data,
1188 find_enc_file = data,
1189 find_sfd_file = data,
1190 find_pk_file = data,
1191 find_data_file = data,
1192 find_opentype_file = data,
1193 find_truetype_file = data,
1194 find_type1_file = data,
1195 find_image_file = data,
1197 % Section 4.1.2: file reading callbacks.
1199 open_read_file = exclusive,
1200 read_font_file = exclusive,
1201 read_vf_file = exclusive,
1202 read_map_file = exclusive,
1203 read_enc_file = exclusive,
1204 read_sfd_file = exclusive,
1205 read_pk_file = exclusive,
1206 read_data_file = exclusive,
1207 read_truetype_file = exclusive,
1208 read_type1_file = exclusive,
1209 read_opentype_file = exclusive,
1211 % \changes{v1.0m}{2016/02/11}{read\_cidmap\_file added}
1212 % Not currently used by luatex but included for completeness.
1213 % may be used by a font handler.
1215 find_cidmap_file = data,
1216 read_cidmap_file = exclusive,
1218 % Section 4.1.3: data processing callbacks.
1219 % \changes{v1.0m}{2016/02/11}{token\_filter removed}
1221 process_input_buffer = data,
1222 process_output_buffer = data,
1223 process_jobname = data,
1225 % Section 4.1.4: node list processing callbacks.
1226 % \changes{v1.0m}{2016/02/11}
1227 % {process\_rule, [hv]pack\_quality append\_to\_vlist\_filter added}
1228 % \changes{v1.0n}{2016/03/13}{insert\_local\_par added}
1229 % \changes{v1.0n}{2016/03/13}{contribute\_filter added}
1231 contribute_filter = simple,
1232 buildpage_filter = simple,
1233 pre_linebreak_filter = list,
1234 linebreak_filter = list,
1235 append_to_vlist_filter = list,
1236 post_linebreak_filter = list,
1237 hpack_filter = list,
1238 vpack_filter = list,
1239 hpack_quality = list,
1240 vpack_quality = list,
1241 pre_output_filter = list,
1242 process_rule = list,
1244 ligaturing = simple,
1246 insert_local_par = simple,
1247 mlist_to_hlist = list,
1249 % Section 4.1.5: information reporting callbacks.
1250 % \changes{v1.0m}{2016/02/11}{show\_warning\_message added}
1255 start_page_number = simple,
1256 stop_page_number = simple,
1257 show_error_hook = simple,
1258 show_warning_message = simple,
1259 show_error_message = simple,
1260 show_lua_error_hook = simple,
1261 start_file = simple,
1264 % Section 4.1.6: PDF-related callbacks.
1266 finish_pdffile = data,
1267 finish_pdfpage = data,
1269 % Section 4.1.7: font-related callbacks.
1271 define_font = exclusive,
1273 % \changes{v1.0m}{2016/02/11}{pdf\_stream\_filter\_callback removed}
1276 luatexbase.callbacktypes=callbacktypes
1279 % \begin{macro}{callback.register}
1280 % \changes{v1.0a}{2015/09/24}{Function modified}
1281 % Save the original function for registering callbacks and prevent the
1282 % original being used. The original is saved in a place that remains
1283 % available so other more sophisticated code can override the approach
1284 % taken by the kernel if desired.
1286 local callback_register = callback_register or callback.register
1287 function callback.register()
1288 luatexbase_error("Attempt to use callback.register() directly\n")
1293 % \subsubsection{Handlers}
1295 % The handler function is registered into the callback when the
1296 % first function is added to this callback's list. Then, when the callback
1297 % is called, the handler takes care of running all functions in the list.
1298 % When the last function is removed from the callback's list, the handler
1301 % More precisely, the functions below are used to generate a specialized
1302 % function (closure) for a given callback, which is the actual handler.
1304 % Handler for |data| callbacks.
1306 local function data_handler(name)
1307 return function(data, ...)
1308 for _,i in ipairs(callbacklist[name]) do
1309 data = i.func(data,...)
1315 % Handler for |exclusive| callbacks. We can assume |callbacklist[name]| is not
1316 % empty: otherwise, the function wouldn't be registered in the callback any
1319 local function exclusive_handler(name)
1320 return function(...)
1321 return callbacklist[name][1].func(...)
1325 % Handler for |list| callbacks.
1326 % \changes{v1.0k}{2015/12/02}{resolve name and i.description (PHG)}
1328 local function list_handler(name)
1329 return function(head, ...)
1331 local alltrue = true
1332 for _,i in ipairs(callbacklist[name]) do
1333 ret = i.func(head, ...)
1334 if ret == false then
1336 "Function `" .. i.description .. "' returned false\n"
1337 .. "in callback `" .. name .."'"
1346 return alltrue and true or head
1350 % Handler for |simple| callbacks.
1352 local function simple_handler(name)
1353 return function(...)
1354 for _,i in ipairs(callbacklist[name]) do
1361 % Keep a handlers table for indexed access.
1364 [data] = data_handler,
1365 [exclusive] = exclusive_handler,
1366 [list] = list_handler,
1367 [simple] = simple_handler,
1371 % \subsubsection{Public functions for callback management}
1373 % Defining user callbacks perhaps should be in package code,
1374 % but impacts on |add_to_callback|.
1375 % If a default function is not required, it may be declared as |false|.
1376 % First we need a list of user callbacks.
1378 local user_callbacks_defaults = { }
1381 % \begin{macro}{create\_callback}
1382 % \changes{v1.0a}{2015/09/24}{Function added}
1383 % \changes{v1.0i}{2015/11/29}{Check name is not nil in error message (PHG)}
1384 % \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
1385 % The allocator itself.
1387 local function create_callback(name, ctype, default)
1388 if not name or name == ""
1389 or not ctype or ctype == ""
1391 luatexbase_error("Unable to create callback:\n" ..
1392 "valid callback name and type required")
1394 if callbacktypes[name] then
1395 luatexbase_error("Unable to create callback `" .. name ..
1396 "':\ncallback type disallowed as name")
1398 if default ~= false and type (default) ~= "function" then
1399 luatexbase_error("Unable to create callback `" .. name ..
1400 ":\ndefault is not a function")
1402 user_callbacks_defaults[name] = default
1403 callbacktypes[name] = types[ctype]
1405 luatexbase.create_callback = create_callback
1409 % \begin{macro}{call\_callback}
1410 % \changes{v1.0a}{2015/09/24}{Function added}
1411 % \changes{v1.0i}{2015/11/29}{Check name is not nil in error message (PHG)}
1412 % \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
1413 % Call a user defined callback. First check arguments.
1415 local function call_callback(name,...)
1416 if not name or name == "" then
1417 luatexbase_error("Unable to create callback:\n" ..
1418 "valid callback name required")
1420 if user_callbacks_defaults[name] == nil then
1421 luatexbase_error("Unable to call callback `" .. name
1422 .. "':\nunknown or empty")
1424 local l = callbacklist[name]
1427 f = user_callbacks_defaults[name]
1432 f = handlers[callbacktypes[name]](name)
1436 luatexbase.call_callback=call_callback
1440 % \begin{macro}{add\_to\_callback}
1441 % \changes{v1.0a}{2015/09/24}{Function added}
1442 % Add a function to a callback. First check arguments.
1443 % \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
1445 local function add_to_callback(name, func, description)
1446 if not name or name == "" then
1447 luatexbase_error("Unable to register callback:\n" ..
1448 "valid callback name required")
1450 if not callbacktypes[name] or
1451 type(func) ~= "function" or
1453 description == "" then
1455 "Unable to register callback.\n\n"
1456 .. "Correct usage:\n"
1457 .. "add_to_callback(<callback>, <function>, <description>)"
1461 % Then test if this callback is already in use. If not, initialise its list
1462 % and register the proper handler.
1464 local l = callbacklist[name]
1467 callbacklist[name] = l
1469 % If it is not a user defined callback use the primitive callback register.
1471 if user_callbacks_defaults[name] == nil then
1472 callback_register(name, handlers[callbacktypes[name]](name))
1476 % Actually register the function and give an error if more than one
1477 % |exclusive| one is registered.
1481 description = description,
1483 local priority = #l + 1
1484 if callbacktypes[name] == exclusive then
1487 "Cannot add second callback to exclusive function\n`" ..
1491 table.insert(l, priority, f)
1493 % Keep user informed.
1496 "Inserting `" .. description .. "' at position "
1497 .. priority .. " in `" .. name .. "'."
1500 luatexbase.add_to_callback = add_to_callback
1504 % \begin{macro}{remove\_from\_callback}
1505 % \changes{v1.0a}{2015/09/24}{Function added}
1506 % \changes{v1.0k}{2015/12/02}{adjust initialisation of cb local (PHG)}
1507 % \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
1508 % Remove a function from a callback. First check arguments.
1510 local function remove_from_callback(name, description)
1511 if not name or name == "" then
1512 luatexbase_error("Unable to remove function from callback:\n" ..
1513 "valid callback name required")
1515 if not callbacktypes[name] or
1517 description == "" then
1519 "Unable to remove function from callback.\n\n"
1520 .. "Correct usage:\n"
1521 .. "remove_from_callback(<callback>, <description>)"
1524 local l = callbacklist[name]
1527 "No callback list for `" .. name .. "'\n")
1530 % Loop over the callback's function list until we find a matching entry.
1531 % Remove it and check if the list is empty: if so, unregister the
1535 for i,j in ipairs(l) do
1536 if j.description == description then
1543 "No callback `" .. description .. "' registered for `" ..
1547 table.remove(l, index)
1549 "Removing `" .. description .. "' from `" .. name .. "'."
1552 callbacklist[name] = nil
1553 callback_register(name, nil)
1555 return cb.func,cb.description
1557 luatexbase.remove_from_callback = remove_from_callback
1561 % \begin{macro}{in\_callback}
1562 % \changes{v1.0a}{2015/09/24}{Function added}
1563 % \changes{v1.0h}{2015/11/27}{Guard against undefined list latex/4445}
1564 % Look for a function description in a callback.
1566 local function in_callback(name, description)
1569 or not callbacklist[name]
1570 or not callbacktypes[name]
1571 or not description then
1574 for _, i in pairs(callbacklist[name]) do
1575 if i.description == description then
1581 luatexbase.in_callback = in_callback
1585 % \begin{macro}{disable\_callback}
1586 % \changes{v1.0a}{2015/09/24}{Function added}
1587 % As we subvert the engine interface we need to provide a way to access
1588 % this functionality.
1590 local function disable_callback(name)
1591 if(callbacklist[name] == nil) then
1592 callback_register(name, false)
1594 luatexbase_error("Callback list for " .. name .. " not empty")
1597 luatexbase.disable_callback = disable_callback
1601 % \begin{macro}{callback\_descriptions}
1602 % \changes{v1.0a}{2015/09/24}{Function added}
1603 % \changes{v1.0h}{2015/11/27}{Match test in in-callback latex/4445}
1604 % List the descriptions of functions registered for the given callback.
1606 local function callback_descriptions (name)
1610 or not callbacklist[name]
1611 or not callbacktypes[name]
1615 for k, i in pairs(callbacklist[name]) do
1621 luatexbase.callback_descriptions =callback_descriptions
1625 % \begin{macro}{uninstall}
1626 % \changes{v1.0e}{2015/10/02}{Function added}
1627 % Unlike at the \TeX{} level, we have to provide a back-out mechanism here
1628 % at the same time as the rest of the code. This is not meant for use by
1629 % anything other than \textsf{latexrelease}: as such this is
1630 % \emph{deliberately} not documented for users!
1632 local function uninstall()
1635 "Uninstalling kernel luatexbase code"
1637 callback.register = callback_register
1640 luatexbase.uninstall = uninstall
1649 % Reset the catcode of |@|.
1651 %<tex>\catcode`\@=\etatcatcode\relax