You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
621 lines
19 KiB
621 lines
19 KiB
--
|
|
-- 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 = simple,
|
|
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 .."'"
|
|
)
|
|
break
|
|
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 .."'"
|
|
)
|
|
break
|
|
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)
|
|
|