summaryrefslogtreecommitdiff
path: root/macros/latex/base/ltluatex.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/base/ltluatex.dtx')
-rw-r--r--macros/latex/base/ltluatex.dtx173
1 files changed, 134 insertions, 39 deletions
diff --git a/macros/latex/base/ltluatex.dtx b/macros/latex/base/ltluatex.dtx
index 41f2344a37..1f9ab8d133 100644
--- a/macros/latex/base/ltluatex.dtx
+++ b/macros/latex/base/ltluatex.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2015-2019
+% Copyright (C) 2015-2020
% The LaTeX3 Project and any individual authors listed elsewhere
% in this file.
%
@@ -28,7 +28,7 @@
\ProvidesFile{ltluatex.dtx}
%</driver>
%<*tex>
-[2019/10/22 v1.1j
+[2020/02/02 v1.1l
%</tex>
%<plain> LuaTeX support for plain TeX (core)
%<*tex>
@@ -152,7 +152,7 @@
%
% \section{Plain \TeX\ interface}
%
-% The \textsf{ltluatex} interface may be used with plain \TeX\ using
+% The \textsf{ltluatex} interface may be used with plain \TeX\ using
% |\input{ltluatex}|. This inputs |ltluatex.tex| which inputs
% |etex.src| (or |etex.sty| if used with \LaTeX)
% if it is not already input, and then defines some internal commands to
@@ -199,7 +199,7 @@
% \noindent
% \DescribeMacro{new_chunkname}
% |luatexbase.new_chunkname(|\meta{chunkname}|)|\\
-% Returns an allocation number for a Lua chunk name for use with
+% Returns an allocation number for a Lua chunk name for use with
% |\directlua| and |\latelua|, indexed from~$1$.
% The number is returned and also \meta{name} argument is added to the
% |lua.name| array at that index.
@@ -339,7 +339,7 @@
% \DescribeMacro{remove_from_callback}
% |luatexbase.remove_from_callback(|\meta{callback}, \meta{description}|)|
% Removes the callback function with \meta{description} from the \meta{callback}.
-% The removed function and its description
+% The removed function and its description
% are returned as the results of this function.
%
% \noindent
@@ -407,7 +407,7 @@
% \end{macrocode}
%
% \subsection{Older \LaTeX{}/Plain \TeX\ setup}
-%
+%
% \begin{macrocode}
%<*tex>
% \end{macrocode}
@@ -473,7 +473,7 @@
% End of proposed changes to \texttt{etex.src}
%
% \subsubsection{luatex specific settings}
-%
+%
% Switch to global cf |luatex.sty| to leave room for inserts
% not really needed for luatex but possibly most compatible
% with existing use.
@@ -675,7 +675,7 @@
\chardef\unicoderead=\numexpr\count16 + 1\relax
\openin\unicoderead=UnicodeData.txt %
\loop\unless\ifeof\unicoderead %
- \read\unicoderead to \unicodedataline
+ \read\unicoderead to \unicodedataline
\unless\ifx\unicodedataline\storedpar
\expandafter\parseunicodedataI\unicodedataline\relax
\fi
@@ -785,7 +785,7 @@
% \end{macrocode}
% Note name change required on older luatex, for hash table access.
% \begin{macrocode}
- \countdef \CountZero =0 %
+ \countdef \CountZero =0 %
\dimendef \dimenzero =0 %
\mathchardef \mathcharzero =0 %
\muskipdef \muskipzero =0 %
@@ -978,7 +978,7 @@ local function msg_format(mod, msg_type, text)
end
return first_head .. " "
.. string_gsub(
- text
+ text
.. "on input line "
.. tex.inputlineno, "\n", "\n" .. cont .. " "
)
@@ -1045,7 +1045,7 @@ local createtoken
if tex.luatexversion > 81 then
createtoken = token.create
elseif tex.luatexversion > 79 then
- createtoken = newtoken.create
+ createtoken = newtoken.create
end
local hashtokens = tex.hashtokens()
local luatexversion = tex.luatexversion
@@ -1134,7 +1134,7 @@ luatexbase.new_attribute = new_attribute
% \begin{macrocode}
local whatsit_count_name = whatsit_count_name or "e@alloc@whatsit@count"
local function new_whatsit(name)
- tex_setcount("global", whatsit_count_name,
+ tex_setcount("global", whatsit_count_name,
tex_count[whatsit_count_name] + 1)
if tex_count[whatsit_count_name] > 65534 then
luatexbase_error("No room for a new custom whatsit")
@@ -1157,7 +1157,7 @@ luatexbase.new_whatsit = new_whatsit
local bytecode_count_name =
bytecode_count_name or "e@alloc@bytecode@count"
local function new_bytecode(name)
- tex_setcount("global", bytecode_count_name,
+ tex_setcount("global", bytecode_count_name,
tex_count[bytecode_count_name] + 1)
if tex_count[bytecode_count_name] > 65534 then
luatexbase_error("No room for a new bytecode register")
@@ -1180,7 +1180,7 @@ luatexbase.new_bytecode = new_bytecode
local chunkname_count_name =
chunkname_count_name or "e@alloc@luachunk@count"
local function new_chunkname(name)
- tex_setcount("global", chunkname_count_name,
+ tex_setcount("global", chunkname_count_name,
tex_count[chunkname_count_name] + 1)
local chunkname_count = tex_count[chunkname_count_name]
chunkname_count = chunkname_count + 1
@@ -1188,7 +1188,7 @@ local function new_chunkname(name)
luatexbase_error("No room for a new chunkname")
end
lua.name[chunkname_count]=name
- luatexbase_log("Lua chunkname " .. (name or "") .. " = " ..
+ luatexbase_log("Lua chunkname " .. (name or "") .. " = " ..
chunkname_count .. "\n")
return chunkname_count
end
@@ -1239,12 +1239,13 @@ local callbacklist = callbacklist or { }
% Numerical codes for callback types, and name-to-value association (the
% table keys are strings, the values are numbers).
% \begin{macrocode}
-local list, data, exclusive, simple = 1, 2, 3, 4
-local types = {
- list = list,
- data = data,
- exclusive = exclusive,
- simple = simple,
+local list, data, exclusive, simple, reverselist = 1, 2, 3, 4, 5
+local types = {
+ list = list,
+ data = data,
+ exclusive = exclusive,
+ simple = simple,
+ reverselist = reverselist,
}
% \end{macrocode}
%
@@ -1319,6 +1320,7 @@ local callbacktypes = callbacktypes or {
% \changes{v1.1k}{2019/10/02}{linebreak\_filter is \texttt{exclusive}}
% \changes{v1.1k}{2019/10/02}{process\_rule is \texttt{exclusive}}
% \changes{v1.1k}{2019/10/02}{mlist\_to\_hlist is \texttt{exclusive}}
+% \changes{v1.1l}{2020/02/02}{post\_linebreak\_filter is \texttt{reverselist}}
% \begin{macrocode}
contribute_filter = simple,
buildpage_filter = simple,
@@ -1326,7 +1328,7 @@ local callbacktypes = callbacktypes or {
pre_linebreak_filter = list,
linebreak_filter = exclusive,
append_to_vlist_filter = exclusive,
- post_linebreak_filter = list,
+ post_linebreak_filter = reverselist,
hpack_filter = list,
vpack_filter = list,
hpack_quality = list,
@@ -1337,7 +1339,9 @@ local callbacktypes = callbacktypes or {
ligaturing = simple,
kerning = simple,
insert_local_par = simple,
+ pre_mlist_to_hlist_filter = list,
mlist_to_hlist = exclusive,
+ post_mlist_to_hlist_filter = reverselist,
new_graf = simple,
% \end{macrocode}
% Section 8.5: information reporting callbacks.
@@ -1366,10 +1370,12 @@ local callbacktypes = callbacktypes or {
% \changes{v1.1j}{2019/06/18}{page\_objnum\_provider added}
% \changes{v1.1j}{2019/06/18}{process\_pdf\_image\_content added}
% \changes{v1.1j}{2019/10/22}{page\_objnum\_provider and process\_pdf\_image\_content classified data}
+% \changes{v1.1l}{2020/02/02}{page\_order\_index added}
% \begin{macrocode}
finish_pdffile = data,
finish_pdfpage = data,
page_objnum_provider = data,
+ page_order_index = data,
process_pdf_image_content = data,
% \end{macrocode}
% Section 8.7: font-related callbacks.
@@ -1377,9 +1383,11 @@ local callbacktypes = callbacktypes or {
% \changes{v1.1g}{2018/05/02}{glyph\_not\_found added}
% \changes{v1.1j}{2019/06/18}{make\_extensible added}
% \changes{v1.1j}{2019/06/18}{font\_descriptor\_objnum\_provider added}
+% \changes{v1.1l}{2020/02/02}{glyph\_info added}
% \begin{macrocode}
define_font = exclusive,
- glyph_not_found = exclusive,
+ glyph_info = exclusive,
+ glyph_not_found = exclusive,
glyph_stream_provider = exclusive,
make_extensible = exclusive,
font_descriptor_objnum_provider = exclusive,
@@ -1437,6 +1445,8 @@ end
% |true|, then the same head is passed to the next function. If all
% functions return |true|, then |true| is returned, otherwise the return
% value of the last function not returning |true| is used.
+% \item[reverselist] is a specialized variant of \emph{list} which executes
+% functions in inverse order.
% \item[exclusive] is for functions with more complex signatures; functions in
% this type of callback are \emph{not} combined: An error is raised if
% a second callback is registered..
@@ -1453,6 +1463,12 @@ local function data_handler(name)
end
end
% \end{macrocode}
+% Default for user-defined |data| callbacks without explicit default.
+% \begin{macrocode}
+local function data_handler_default(value)
+ return value
+end
+% \end{macrocode}
% Handler for |exclusive| callbacks. We can assume |callbacklist[name]| is not
% empty: otherwise, the function wouldn't be registered in the callback any
% more.
@@ -1488,6 +1504,39 @@ local function list_handler(name)
end
end
% \end{macrocode}
+% Default for user-defined |list| and |reverselist| callbacks without explicit default.
+% \begin{macrocode}
+local function list_handler_default()
+ return true
+end
+% \end{macrocode}
+% Handler for |reverselist| callbacks.
+% \changes{v1.1l}{2020/02/02}{Add reverselist callback type}
+% \begin{macrocode}
+local function reverselist_handler(name)
+ return function(head, ...)
+ local ret
+ local alltrue = true
+ local callbacks = callbacklist[name]
+ for i = #callbacks, 1, -1 do
+ local cb = callbacks[i]
+ ret = cb.func(head, ...)
+ if ret == false then
+ luatexbase_warning(
+ "Function `" .. cb.description .. "' returned false\n"
+ .. "in callback `" .. name .."'"
+ )
+ break
+ end
+ if ret ~= true then
+ alltrue = false
+ head = ret
+ end
+ end
+ return alltrue and true or head
+ end
+end
+% \end{macrocode}
% Handler for |simple| callbacks.
% \begin{macrocode}
local function simple_handler(name)
@@ -1498,14 +1547,27 @@ local function simple_handler(name)
end
end
% \end{macrocode}
+% Default for user-defined |simple| callbacks without explicit default.
+% \begin{macrocode}
+local function simple_handler_default()
+end
+% \end{macrocode}
%
-% Keep a handlers table for indexed access.
+% Keep a handlers table for indexed access and a table with the corresponding default functions.
% \begin{macrocode}
-local handlers = {
- [data] = data_handler,
- [exclusive] = exclusive_handler,
- [list] = list_handler,
- [simple] = simple_handler,
+local handlers = {
+ [data] = data_handler,
+ [exclusive] = exclusive_handler,
+ [list] = list_handler,
+ [reverselist] = reverselist_handler,
+ [simple] = simple_handler,
+}
+local defaults = {
+ [data] = data_handler_default,
+ [exclusive] = nil,
+ [list] = list_handler_default,
+ [reverselist] = list_handler_default,
+ [simple] = simple_handler_default,
}
% \end{macrocode}
%
@@ -1516,18 +1578,24 @@ local handlers = {
% If a default function is not required, it may be declared as |false|.
% First we need a list of user callbacks.
% \begin{macrocode}
-local user_callbacks_defaults = { }
+local user_callbacks_defaults = {
+ pre_mlist_to_hlist_filter = list_handler_default,
+ mlist_to_hlist = node.mlist_to_hlist,
+ post_mlist_to_hlist_filter = list_handler_default,
+}
% \end{macrocode}
%
% \begin{macro}{create_callback}
% \changes{v1.0a}{2015/09/24}{Function added}
% \changes{v1.0i}{2015/11/29}{Check name is not nil in error message (PHG)}
% \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
+% \changes{v1.1l}{2020/02/02}{Provide proper fallbacks for user-defined callbacks without user-provided default handler}
% The allocator itself.
% \begin{macrocode}
local function create_callback(name, ctype, default)
+ local ctype_id = types[ctype]
if not name or name == ""
- or not ctype or ctype == ""
+ or not ctype_id
then
luatexbase_error("Unable to create callback:\n" ..
"valid callback name and type required")
@@ -1536,12 +1604,17 @@ local function create_callback(name, ctype, default)
luatexbase_error("Unable to create callback `" .. name ..
"':\ncallback is already defined")
end
- if default ~= false and type (default) ~= "function" then
+ default = default or defaults[ctype_id]
+ if not default then
luatexbase_error("Unable to create callback `" .. name ..
- ":\ndefault is not a function")
- end
+ "':\ndefault is required for `" .. ctype ..
+ "' callbacks")
+ elseif type (default) ~= "function" then
+ luatexbase_error("Unable to create callback `" .. name ..
+ "':\ndefault is not a function")
+ end
user_callbacks_defaults[name] = default
- callbacktypes[name] = types[ctype]
+ callbacktypes[name] = ctype_id
end
luatexbase.create_callback = create_callback
% \end{macrocode}
@@ -1566,9 +1639,6 @@ local function call_callback(name,...)
local f
if not l then
f = user_callbacks_defaults[name]
- if l == false then
- return nil
- end
else
f = handlers[callbacktypes[name]](name)
end
@@ -1759,7 +1829,7 @@ local function callback_descriptions (name)
end
return d
end
-luatexbase.callback_descriptions =callback_descriptions
+luatexbase.callback_descriptions =callback_descriptions
% \end{macrocode}
% \end{macro}
%
@@ -1781,6 +1851,31 @@ end
luatexbase.uninstall = uninstall
% \end{macrocode}
% \end{macro}
+% \begin{macro}{mlist_to_hlist}
+% \changes{v1.1l}{2020/02/02}{|pre/post_mlist_to_hlist| added}
+% To emulate these callbacks, the ``real'' |mlist_to_hlist| is replaced by a
+% wrapper calling the wrappers before and after.
+% \begin{macrocode}
+callback_register("mlist_to_hlist", function(head, display_type, need_penalties)
+ local current = call_callback("pre_mlist_to_hlist_filter", head, display_type, need_penalties)
+ if current == false then
+ flush_list(head)
+ return nil
+ elseif current == true then
+ current = head
+ end
+ current = call_callback("mlist_to_hlist", current, display_type, need_penalties)
+ local post = call_callback("post_mlist_to_hlist_filter", current, display_type, need_penalties)
+ if post == true then
+ return current
+ elseif post == false then
+ flush_list(current)
+ return nil
+ end
+ return post
+end)
+% \end{macrocode}
+% \end{macro}
% \endgroup
%
% \begin{macrocode}