luametalatex/luametalatex-lateinit.lua

167 lines
5.3 KiB
Lua
Raw Normal View History

luametalatex = luametalatex or {}
local lmlt = luametalatex
2020-07-04 06:27:30 +02:00
local initex = status.ini_version
if initex then
lua.prepared_code = {false}
end
bit32 = require'luametalatex-bit32' -- Why? And why so early?
status.init_kpse = 1 -- Why?
status.safer_option = 0 -- compat
status.shell_escape = 0 -- compat -- This is currently a lie.
-- require'module' -- ???
pdf = {
variable = {},
}
require'luametalatex-font-resolve' -- Replace font.define. Must be loaded before callbacks
2020-07-15 16:36:11 +02:00
require'luametalatex-basecallbacks'
2021-11-06 11:38:39 +01:00
require'luametalatex-oldnames'
local callbacks = require'luametalatex-callbacks'
2020-07-04 06:27:30 +02:00
2021-03-20 19:00:02 +01:00
local function swap_table(t)
local s = {}
for k, v in next, t do
s[v] = k
end
return s
end
local primitives = {}
do
2021-03-20 19:00:02 +01:00
local token_primitives = token.getprimitives()
local token_new = token.new
for i=1,#token_primitives do
local prim = token_primitives[i]
primitives[prim[3]] = token_new(prim[2], prim[1])
end
end
lmlt.primitive_tokens = primitives
2021-03-20 19:00:02 +01:00
do
local command_id = swap_table(token.getcommandvalues())
function token.command_id(name) return command_id[name] end
end
lmlt.value = swap_table(token.getfunctionvalues())
lmlt.flag = swap_table(tex.getflagvalues())
2021-03-20 19:00:02 +01:00
2020-07-04 06:27:30 +02:00
local functions = lua.getfunctionstable()
-- I am not sure why this is necessary, but otherwise LuaMetaTeX resets
-- the functions table every time the getter is called
function lua.get_functions_table() return functions end
local set_lua = token.set_lua
-- There are two approaches to manage luafunctions ids without triggering
-- issues with ltluatex assigned numbers: Originally we assigned numbers
-- starting with 1, then switched to luatexbase ASAP and synchronised both
-- numbering schemes. But there is a useful quirk in ltluatex's luafunction
-- allocator: It only uses numbers upto 65535, so we can just use bigger
-- numbers. (This might have negative repercussins on performance because it
-- probably doesn't store the function in the array part of the Lua table.
-- Let's reconsider if this ever becomes a problem.
-- local new_luafunction = luatexbase.new_luafunction
local predefined_luafunctions = initex and 65536 -- 1<<16 -- We start with 1<<16 + 1 (1<<16=65536 is reserved for luametalatex-local)
local new_luafunction
function new_luafunction(name)
if predefined_luafunctions then
predefined_luafunctions = predefined_luafunctions + 1
return predefined_luafunctions
else
error[[Here only preexisting luafunctions should be set]]
end
end
local undefined_cmd = token.command_id'undefined_cs'
local lua_call_cmd = token.command_id'lua_call'
local lua_value_cmd = token.command_id'lua_value'
2021-04-16 10:15:58 +02:00
local lua_protected_call_cmd = token.command_id'lua_protected_call'
local if_test_cmd = token.command_id'if_test'
function lmlt.luacmd(name, func, ...)
2020-07-04 06:27:30 +02:00
local idx
local tok = token.create(name)
local cmd = tok.command
if cmd == lua_value_cmd then
2020-07-07 16:52:06 +02:00
idx = tok.index
2020-07-04 06:27:30 +02:00
elseif cmd == lua_call_cmd then
2020-07-07 16:52:06 +02:00
idx = tok.index
2021-04-16 10:15:58 +02:00
elseif cmd == lua_protected_call_cmd then
2020-07-07 16:52:06 +02:00
idx = tok.index
2021-11-06 11:38:39 +01:00
elseif cmd == if_test_cmd and tok.index > 53 then
idx = tok.index - 53
2020-07-04 06:27:30 +02:00
elseif ... == 'force' then
idx = new_luafunction(name)
set_lua(name, idx, select(2, ...))
elseif cmd == undefined_cmd then
idx = new_luafunction(name)
set_lua(name, idx, ...)
else
error(tok.cmdname)
end
if functions[idx] then
error[[Already defined]]
end
functions[idx] = func
return idx
end
if initex then
local build_bytecode = nil -- To be filled
local output_directory = arg['output-directory']
function callbacks.pre_dump()
local user_callback = callbacks.pre_dump
if user_callback then user_callback() end
2020-07-04 06:27:30 +02:00
local prepared = lua.prepared_code
prepared[1] = string.format("fixupluafunctions(%i)", predefined_luafunctions)
for i=0,status.languagestate.ptr do
2021-03-20 19:00:02 +01:00
local l = language.new(i)
2020-07-04 06:27:30 +02:00
local str = string.format("do \z
2021-03-20 19:00:02 +01:00
local l = language.new(%i)\z
2020-07-04 06:27:30 +02:00
l:hyphenationmin(%i)\z
l:prehyphenchar(%i)\z
l:posthyphenchar(%i)\z
l:preexhyphenchar(%i)\z
l:postexhyphenchar(%i)",
i,
l:hyphenationmin(),
l:prehyphenchar(),
l:posthyphenchar(),
l:preexhyphenchar(),
l:postexhyphenchar())
local patterns = l:patterns()
local exceptions = l:hyphenation()
if patterns and exceptions then
str = string.format("%sl:patterns(%q)l:hyphenation(%q)end", str, patterns, exceptions)
elseif patterns then
str = string.format("%sl:patterns(%q)end", str, patterns)
elseif exceptions then
str = string.format("%sl:hyphenation(%q)end", str, exceptions)
else
str = str .. 'end'
end
prepared[#prepared+1] = str
end
for i=2,#prepared do
if type(prepared[i]) ~= 'string' then
prepared[i] = assert(prepared[i]())
end
end
lua.bytecode[tex.count[262]+1] = build_bytecode(table.concat(prepared, '\n'))
if output_directory then
lfs.chdir(output_directory) -- We can't change the location TeX writes it's format to, so we change the current directory instead
end
end
callbacks.__freeze('pre_dump', true)
2020-07-04 06:27:30 +02:00
return function(f)
build_bytecode = f
return require'luametalatex-firstcode'
end
else
function fixupluafunctions(i)
predefined_luafunctions = i
fixupluafunctions = nil
end
return function(f)
f()
return require'luametalatex-firstcode'
end
end