Current File : //usr/share/texlive/texmf-dist/tex/latex/base/ltluatex.lua |
--
-- This is file `ltluatex.lua',
-- generated with the docstrip utility.
--
-- The original source files were:
--
-- ltluatex.dtx (with options: `lua')
--
-- This is a generated file.
--
-- The source is maintained by the LaTeX Project team and bug
-- reports for it can be opened at https://latex-project.org/bugs.html
-- (but please observe conditions on bug reports sent to that address!)
--
--
-- Copyright 2015
-- The LaTeX3 Project and any individual authors listed elsewhere
-- in this file.
--
-- This file was generated from file(s) of the LaTeX base system.
-- --------------------------------------------------------------
--
-- It may be distributed and/or modified under the
-- conditions of the LaTeX Project Public License, either version 1.3c
-- of this license or (at your option) any later version.
-- The latest version of this license is in
-- https://www.latex-project.org/lppl.txt
-- and version 1.3c or later is part of all distributions of LaTeX
-- version 2008 or later.
--
-- This file has the LPPL maintenance status "maintained".
--
-- This file may only be distributed together with a copy of the LaTeX
-- base system. You may however distribute the LaTeX base system without
-- such generated files.
--
-- The list of all files belonging to the LaTeX base distribution is
-- given in the file `manifest.txt'. See also `legal.txt' for additional
-- information.
--
-- The list of derived (unpacked) files belonging to the distribution
-- and covered by LPPL is defined by the unpacking scripts (with
-- extension .ins) which are part of the distribution.
luatexbase = luatexbase or { }
local luatexbase = luatexbase
local string_gsub = string.gsub
local tex_count = tex.count
local tex_setattribute = tex.setattribute
local tex_setcount = tex.setcount
local texio_write_nl = texio.write_nl
local luatexbase_warning
local luatexbase_error
local modules = modules or { }
local function luatexbase_log(text)
texio_write_nl("log", text)
end
local function provides_module(info)
if not (info and info.name) then
luatexbase_error("Missing module name for provides_module")
end
local function spaced(text)
return text and (" " .. text) or ""
end
luatexbase_log(
"Lua module: " .. info.name
.. spaced(info.date)
.. spaced(info.version)
.. spaced(info.description)
)
modules[info.name] = info
end
luatexbase.provides_module = provides_module
local function msg_format(mod, msg_type, text)
local leader = ""
local cont
local first_head
if mod == "LaTeX" then
cont = string_gsub(leader, ".", " ")
first_head = leader .. "LaTeX: "
else
first_head = leader .. "Module " .. msg_type
cont = "(" .. mod .. ")"
.. string_gsub(first_head, ".", " ")
first_head = leader .. "Module " .. mod .. " " .. msg_type .. ":"
end
if msg_type == "Error" then
first_head = "\n" .. first_head
end
if string.sub(text,-1) ~= "\n" then
text = text .. " "
end
return first_head .. " "
.. string_gsub(
text
.. "on input line "
.. tex.inputlineno, "\n", "\n" .. cont .. " "
)
.. "\n"
end
local function module_info(mod, text)
texio_write_nl("log", msg_format(mod, "Info", text))
end
luatexbase.module_info = module_info
local function module_warning(mod, text)
texio_write_nl("term and log",msg_format(mod, "Warning", text))
end
luatexbase.module_warning = module_warning
local function module_error(mod, text)
error(msg_format(mod, "Error", text))
end
luatexbase.module_error = module_error
function luatexbase_warning(text)
module_warning("luatexbase", text)
end
function luatexbase_error(text)
module_error("luatexbase", text)
end
local luaregisterbasetable = { }
local registermap = {
attributezero = "assign_attr" ,
charzero = "char_given" ,
CountZero = "assign_int" ,
dimenzero = "assign_dimen" ,
mathcharzero = "math_given" ,
muskipzero = "assign_mu_skip" ,
skipzero = "assign_skip" ,
tokszero = "assign_toks" ,
}
local createtoken
if tex.luatexversion > 81 then
createtoken = token.create
elseif tex.luatexversion > 79 then
createtoken = newtoken.create
end
local hashtokens = tex.hashtokens()
local luatexversion = tex.luatexversion
for i,j in pairs (registermap) do
if luatexversion < 80 then
luaregisterbasetable[hashtokens[i][1]] =
hashtokens[i][2]
else
luaregisterbasetable[j] = createtoken(i).mode
end
end
local registernumber
if luatexversion < 80 then
function registernumber(name)
local nt = hashtokens[name]
if(nt and luaregisterbasetable[nt[1]]) then
return nt[2] - luaregisterbasetable[nt[1]]
else
return false
end
end
else
function registernumber(name)
local nt = createtoken(name)
if(luaregisterbasetable[nt.cmdname]) then
return nt.mode - luaregisterbasetable[nt.cmdname]
else
return false
end
end
end
luatexbase.registernumber = registernumber
local attributes=setmetatable(
{},
{
__index = function(t,key)
return registernumber(key) or nil
end}
)
luatexbase.attributes = attributes
local attribute_count_name =
attribute_count_name or "e@alloc@attribute@count"
local function new_attribute(name)
tex_setcount("global", attribute_count_name,
tex_count[attribute_count_name] + 1)
if tex_count[attribute_count_name] > 65534 then
luatexbase_error("No room for a new \\attribute")
end
attributes[name]= tex_count[attribute_count_name]
luatexbase_log("Lua-only attribute " .. name .. " = " ..
tex_count[attribute_count_name])
return tex_count[attribute_count_name]
end
luatexbase.new_attribute = new_attribute
local whatsit_count_name = whatsit_count_name or "e@alloc@whatsit@count"
local function new_whatsit(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")
end
luatexbase_log("Custom whatsit " .. (name or "") .. " = " ..
tex_count[whatsit_count_name])
return tex_count[whatsit_count_name]
end
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_count[bytecode_count_name] + 1)
if tex_count[bytecode_count_name] > 65534 then
luatexbase_error("No room for a new bytecode register")
end
luatexbase_log("Lua bytecode " .. (name or "") .. " = " ..
tex_count[bytecode_count_name])
return tex_count[bytecode_count_name]
end
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_count[chunkname_count_name] + 1)
local chunkname_count = tex_count[chunkname_count_name]
chunkname_count = chunkname_count + 1
if chunkname_count > 65534 then
luatexbase_error("No room for a new chunkname")
end
lua.name[chunkname_count]=name
luatexbase_log("Lua chunkname " .. (name or "") .. " = " ..
chunkname_count .. "\n")
return chunkname_count
end
luatexbase.new_chunkname = new_chunkname
local luafunction_count_name =
luafunction_count_name or "e@alloc@luafunction@count"
local function new_luafunction(name)
tex_setcount("global", luafunction_count_name,
tex_count[luafunction_count_name] + 1)
if tex_count[luafunction_count_name] > 65534 then
luatexbase_error("No room for a new luafunction register")
end
luatexbase_log("Lua function " .. (name or "") .. " = " ..
tex_count[luafunction_count_name])
return tex_count[luafunction_count_name]
end
luatexbase.new_luafunction = new_luafunction
local callbacklist = callbacklist or { }
local list, data, exclusive, simple, reverselist = 1, 2, 3, 4, 5
local types = {
list = list,
data = data,
exclusive = exclusive,
simple = simple,
reverselist = reverselist,
}
local callbacktypes = callbacktypes or {
find_read_file = exclusive,
find_write_file = exclusive,
find_font_file = data,
find_output_file = data,
find_format_file = data,
find_vf_file = data,
find_map_file = data,
find_enc_file = data,
find_pk_file = data,
find_data_file = data,
find_opentype_file = data,
find_truetype_file = data,
find_type1_file = data,
find_image_file = data,
open_read_file = exclusive,
read_font_file = exclusive,
read_vf_file = exclusive,
read_map_file = exclusive,
read_enc_file = exclusive,
read_pk_file = exclusive,
read_data_file = exclusive,
read_truetype_file = exclusive,
read_type1_file = exclusive,
read_opentype_file = exclusive,
find_cidmap_file = data,
read_cidmap_file = exclusive,
process_input_buffer = data,
process_output_buffer = data,
process_jobname = data,
contribute_filter = simple,
buildpage_filter = simple,
build_page_insert = exclusive,
pre_linebreak_filter = list,
linebreak_filter = exclusive,
append_to_vlist_filter = exclusive,
post_linebreak_filter = reverselist,
hpack_filter = list,
vpack_filter = list,
hpack_quality = list,
vpack_quality = list,
pre_output_filter = list,
process_rule = exclusive,
hyphenate = simple,
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 = exclusive,
pre_dump = simple,
start_run = simple,
stop_run = simple,
start_page_number = simple,
stop_page_number = simple,
show_error_hook = simple,
show_warning_message = simple,
show_error_message = simple,
show_lua_error_hook = simple,
start_file = simple,
stop_file = simple,
call_edit = simple,
finish_synctex = simple,
wrapup_run = simple,
finish_pdffile = data,
finish_pdfpage = data,
page_objnum_provider = data,
page_order_index = data,
process_pdf_image_content = data,
define_font = exclusive,
glyph_info = exclusive,
glyph_not_found = exclusive,
glyph_stream_provider = exclusive,
make_extensible = exclusive,
font_descriptor_objnum_provider = exclusive,
}
luatexbase.callbacktypes=callbacktypes
local callback_register = callback_register or callback.register
function callback.register()
luatexbase_error("Attempt to use callback.register() directly\n")
end
local function data_handler(name)
return function(data, ...)
for _,i in ipairs(callbacklist[name]) do
data = i.func(data,...)
end
return data
end
end
local function data_handler_default(value)
return value
end
local function exclusive_handler(name)
return function(...)
return callbacklist[name][1].func(...)
end
end
local function list_handler(name)
return function(head, ...)
local ret
local alltrue = true
for _,i in ipairs(callbacklist[name]) do
ret = i.func(head, ...)
if ret == false then
luatexbase_warning(
"Function `" .. i.description .. "' returned false\n"
.. "in callback `" .. name .."'"
)
return false
end
if ret ~= true then
alltrue = false
head = ret
end
end
return alltrue and true or head
end
end
local function list_handler_default()
return true
end
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 .."'"
)
return false
end
if ret ~= true then
alltrue = false
head = ret
end
end
return alltrue and true or head
end
end
local function simple_handler(name)
return function(...)
for _,i in ipairs(callbacklist[name]) do
i.func(...)
end
end
end
local function simple_handler_default()
end
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,
}
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,
}
local function create_callback(name, ctype, default)
local ctype_id = types[ctype]
if not name or name == ""
or not ctype_id
then
luatexbase_error("Unable to create callback:\n" ..
"valid callback name and type required")
end
if callbacktypes[name] then
luatexbase_error("Unable to create callback `" .. name ..
"':\ncallback is already defined")
end
default = default or defaults[ctype_id]
if not default then
luatexbase_error("Unable to create callback `" .. name ..
"':\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] = ctype_id
end
luatexbase.create_callback = create_callback
local function call_callback(name,...)
if not name or name == "" then
luatexbase_error("Unable to create callback:\n" ..
"valid callback name required")
end
if user_callbacks_defaults[name] == nil then
luatexbase_error("Unable to call callback `" .. name
.. "':\nunknown or empty")
end
local l = callbacklist[name]
local f
if not l then
f = user_callbacks_defaults[name]
else
f = handlers[callbacktypes[name]](name)
end
return f(...)
end
luatexbase.call_callback=call_callback
local function add_to_callback(name, func, description)
if not name or name == "" then
luatexbase_error("Unable to register callback:\n" ..
"valid callback name required")
end
if not callbacktypes[name] or
type(func) ~= "function" or
not description or
description == "" then
luatexbase_error(
"Unable to register callback.\n\n"
.. "Correct usage:\n"
.. "add_to_callback(<callback>, <function>, <description>)"
)
end
local l = callbacklist[name]
if l == nil then
l = { }
callbacklist[name] = l
if user_callbacks_defaults[name] == nil then
callback_register(name, handlers[callbacktypes[name]](name))
end
end
local f = {
func = func,
description = description,
}
local priority = #l + 1
if callbacktypes[name] == exclusive then
if #l == 1 then
luatexbase_error(
"Cannot add second callback to exclusive function\n`" ..
name .. "'")
end
end
table.insert(l, priority, f)
luatexbase_log(
"Inserting `" .. description .. "' at position "
.. priority .. " in `" .. name .. "'."
)
end
luatexbase.add_to_callback = add_to_callback
local function remove_from_callback(name, description)
if not name or name == "" then
luatexbase_error("Unable to remove function from callback:\n" ..
"valid callback name required")
end
if not callbacktypes[name] or
not description or
description == "" then
luatexbase_error(
"Unable to remove function from callback.\n\n"
.. "Correct usage:\n"
.. "remove_from_callback(<callback>, <description>)"
)
end
local l = callbacklist[name]
if not l then
luatexbase_error(
"No callback list for `" .. name .. "'\n")
end
local index = false
for i,j in ipairs(l) do
if j.description == description then
index = i
break
end
end
if not index then
luatexbase_error(
"No callback `" .. description .. "' registered for `" ..
name .. "'\n")
end
local cb = l[index]
table.remove(l, index)
luatexbase_log(
"Removing `" .. description .. "' from `" .. name .. "'."
)
if #l == 0 then
callbacklist[name] = nil
if user_callbacks_defaults[name] == nil then
callback_register(name, nil)
end
end
return cb.func,cb.description
end
luatexbase.remove_from_callback = remove_from_callback
local function in_callback(name, description)
if not name
or name == ""
or not callbacklist[name]
or not callbacktypes[name]
or not description then
return false
end
for _, i in pairs(callbacklist[name]) do
if i.description == description then
return true
end
end
return false
end
luatexbase.in_callback = in_callback
local function disable_callback(name)
if(callbacklist[name] == nil) then
callback_register(name, false)
else
luatexbase_error("Callback list for " .. name .. " not empty")
end
end
luatexbase.disable_callback = disable_callback
local function callback_descriptions (name)
local d = {}
if not name
or name == ""
or not callbacklist[name]
or not callbacktypes[name]
then
return d
else
for k, i in pairs(callbacklist[name]) do
d[k]= i.description
end
end
return d
end
luatexbase.callback_descriptions =callback_descriptions
local function uninstall()
module_info(
"luatexbase",
"Uninstalling kernel luatexbase code"
)
callback.register = callback_register
luatexbase = nil
end
luatexbase.uninstall = uninstall
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)