From c0954fe7f618da869fe5b5bed9b46a81150dbe83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Thu, 28 May 2020 14:37:19 +0200 Subject: [PATCH] Better luafunction handling and fixes --- luametalatex-back-pdf.lua | 10 ++++-- luametalatex-baseregisters.tex | 20 +++++++++-- luametalatex-dir-registers.lua | 44 ++++++++++++++++++++++++ luametalatex-firstcode.lua | 61 +++++++++++++++++++++++++++------- luametalatex-init.lua | 10 +++--- luametalatex.ini | 38 ++++----------------- 6 files changed, 128 insertions(+), 55 deletions(-) create mode 100644 luametalatex-dir-registers.lua diff --git a/luametalatex-back-pdf.lua b/luametalatex-back-pdf.lua index 5e6fe3e..1176ce4 100644 --- a/luametalatex-back-pdf.lua +++ b/luametalatex-back-pdf.lua @@ -1,7 +1,7 @@ local pdf = pdf local writer = require'luametalatex-nodewriter' local newpdf = require'luametalatex-pdf' -local pfile = newpdf.open(tex.jobname .. '.pdf') +local pfile local fontdirs = setmetatable({}, {__index=function(t, k)t[k] = pfile:getobj() return t[k] end}) local usedglyphs = {} local colorstacks = {{ @@ -12,6 +12,9 @@ local colorstacks = {{ }} token.scan_list = token.scan_box -- They are equal if no parameter is present token.luacmd("shipout", function() + if not pfile then + pfile = newpdf.open(tex.jobname .. '.pdf') + end local voff = node.new'kern' voff.kern = tex.voffset + pdf.variable.vorigin voff.next = token.scan_list() @@ -25,7 +28,7 @@ token.luacmd("shipout", function() pfile:indirect(page, string.format([[<>]], parent, content, -math.ceil(list.depth/65781.76), math.ceil(list.width/65781.76), math.ceil(list.height/65781.76), resources, annots)) token.put_next(token.create'immediateassignment', token.create'global', token.create'deadcycles', token.create(0x30), token.create'relax') token.scan_token() -end, 'protected') +end, 'force', 'protected') local infodir = "" local creationdate = os.date("D:%Y%m%d%H%M%S%z"):gsub("+0000$", "Z"):gsub("%d%d$", "'%0") local function write_infodir(p) @@ -48,6 +51,9 @@ local function write_infodir(p) return p:indirect(nil, string.format("<<%s%s>>", infodir, additional)) end callback.register("stop_run", function() + if not pfile then + return + end for fid, id in pairs(fontdirs) do local f = font.getfont(fid) local psname = f.psname or f.fullname diff --git a/luametalatex-baseregisters.tex b/luametalatex-baseregisters.tex index 59e4d1b..31d7dd2 100644 --- a/luametalatex-baseregisters.tex +++ b/luametalatex-baseregisters.tex @@ -91,9 +91,23 @@ \pdfAlloc{count}{minorversion}{7} \pdfAlloc{count}{compresslevel}{0} % 0 is actually the only supported value right now, so this is basically ignored \pdfAlloc{count}{objcompresslevel}{0} % see above -\directlua{ - lua.prepared_code[\csstring#lua.prepared_code+1] = tex.toks[0] .. "end" - \the\toks0 + +\texAlloc{count}{bodydirection}{0} +\texAlloc{count}{pagedirection}{0} +\etoksapp0{ + function tex.getbodydir() return tex.bodydirection end + function tex.getpagedir() return tex.pagedirection end + function tex.setbodydir(i) tex.bodydirection = i end + function tex.setpagedir(i) tex.pagedirection = i end + local dir_regs = require 'luametalatex-dir-registers' + dir_regs 'textdir' + dir_regs 'bodydir' + dir_regs 'pagedir' end } + +\directlua{ + lua.prepared_code[\csstring#lua.prepared_code+1] = tex.toks[0] + \the\toks0 +} \endgroup diff --git a/luametalatex-dir-registers.lua b/luametalatex-dir-registers.lua new file mode 100644 index 0000000..fdc876a --- /dev/null +++ b/luametalatex-dir-registers.lua @@ -0,0 +1,44 @@ +-- local names = {} +local setters = { +} +local getters = { +} +local value_values = token.values'value' +for i=0,#value_values do + value_values[value_values[i]] = i +end +function tex.gettextdir() return tex.textdirection end +function tex.getlinedir() return tex.linedirection end +function tex.getmathdir() return tex.mathdirection end +function tex.getpardir() return tex.pardirection end +-- local integer_code = value_values.none +local integer_code = value_values.integer +local functions = lua.get_functions_table() +local lua_call_cmd = token.command_id'lua_call' +local function set_xdir(id, scanning) + -- local name = names[id] + if scanning then + return integer_code, getters[id]() + -- return integer_code, tex[name .. 'ection'] + end + local value + if token.scan_keyword'tlt' then + value = 0 + elseif token.scan_keyword'trt' then + value = 1 + else + value = token.scan_int() + end + setters[id](value) + -- tex["set" .. name](value) +end +return function(name) + local getter = tex["get" .. name] + local setter = tex["set" .. name] + assert(getter and setter, "direction parameter undefined") + local idx = token.luacmd(name, set_xdir, "protected", "global", "value") + -- names[idx] = name + getters[idx] = getter + setters[idx] = setter + return idx +end diff --git a/luametalatex-firstcode.lua b/luametalatex-firstcode.lua index 190162b..ee33929 100644 --- a/luametalatex-firstcode.lua +++ b/luametalatex-firstcode.lua @@ -3,15 +3,50 @@ local functions = lua.getfunctionstable() -- 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 = 0 +local predefined_luafunctions = status.ini_version and 65535 -- 1<<16 - 1 -- We start with 1<<16 local function new_luafunction(name) - predefined_luafunctions = predefined_luafunctions + 1 - return predefined_luafunctions + 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' +local lua_expandable_call_cmd = token.command_id'lua_expandable_call' function token.luacmd(name, func, ...) - local idx = new_luafunction(name) - set_lua(name, idx, ...) + local idx + local tok = token.create(name) + local cmd = tok.command + if cmd == lua_value_cmd then + idx = tok.mode + elseif cmd == lua_call_cmd then + idx = tok.mode + elseif cmd == lua_expandable_call_cmd then + idx = tok.mode + 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 @@ -154,13 +189,12 @@ token.luacmd("write", function(_, immediate) -- \write end end, "protected") -local lua_call_cmd = token.command_id'lua_call' token.luacmd("immediate", function() -- \immediate local next_tok = token.scan_token() if next_tok.command ~= lua_call_cmd then return token.put_next(next_tok) end - local function_id = next_tok.index + local function_id = next_tok.mode functions[function_id](function_id, 'immediate') end, "protected") -- functions[43] = function() -- \pdfvariable @@ -169,15 +203,18 @@ end, "protected") -- end if status.ini_version then function fixupluafunctions() - tex.setcount("global", "e@alloc@luafunction@count", predefined_luafunctions) + return predefined_luafunctions end else + function fixupluafunctions(i) + predefined_luafunctions = i + end local prepared_code = lua.bytecode[1] prepared_code() lua.bytecode[1] = nil - function fixupluafunctions() - new_luafunction = luatexbase.new_luafunction - fixupluafunctions = nil - end + -- function fixupluafunctions() + -- new_luafunction = luatexbase.new_luafunction + -- fixupluafunctions = nil + -- end end require'luametalatex-back-pdf' diff --git a/luametalatex-init.lua b/luametalatex-init.lua index 867fee7..98e4322 100644 --- a/luametalatex-init.lua +++ b/luametalatex-init.lua @@ -30,6 +30,7 @@ kpse.init_prog("LUATEX", 400, "nexthi", nil) status.init_kpse = 1 require'luametalatex-init-config' status.safer_option = 0 +status.shell_escape = 0 local read_tfm = require'luametalatex-font-tfm' local read_vf = require'luametalatex-font-vf' font.read_tfm = read_tfm @@ -58,10 +59,6 @@ callback.register('define_font', function(name, size) end return id end) --- callback.register('terminal_input', function(prompt) - -- print('Input expected: ', prompt) - -- return 'AAA' --- end) callback.register('find_log_file', function(name) return name end) -- callback.register('find_read_file', function(i, name) return kpse.find_file(name, 'tex', true) end) callback.register('find_data_file', function(name, ...) return kpse.find_file(name, 'tex', true) end) @@ -88,16 +85,17 @@ callback.register('show_error_message', function() texio.write_nl(status.lasterrorstring) end) callback.register('pre_dump', function() + lua.prepared_code[1] = string.format("fixupluafunctions(%i)", fixupluafunctions()) lua.bytecode[1] = assert(load(table.concat(lua.prepared_code, ' '))) end) function texconfig.init() + lua.bytecode[2]() if not status.ini_version then - lua.bytecode[2]() lua.bytecode[2] = nil end end if status.ini_version then - lua.prepared_code = {} + lua.prepared_code = {false} local code = package.searchers[2]('luametalatex-firstcode') if type(code) == "string" then error(string.format("Initialization code not found %s", code)) end lua.bytecode[2] = code diff --git a/luametalatex.ini b/luametalatex.ini index 3582e7c..2be29e6 100644 --- a/luametalatex.ini +++ b/luametalatex.ini @@ -1,40 +1,14 @@ % Thomas Esser, 1998. public domain. % -\ifx\pdfoutput\undefined \else - \ifx\pdfoutput\relax \else - % - % We're building the latex format with the pdfetex engine (started 2004). - \input pdftexconfig - \pdfoutput=0 - % - % pdfTeX related primitives are no longer hidden by default - % (started 2005). Uncomment and recreate the format files by running - % "fmtutil --all" resp. "fmtutil-sys --all" to revert to the old - % (2004) behaviour. - % \input pdftex-dvi.tex - % - \fi -\fi -% -% the usual format initialization. + \scrollmode -\luabytecode2 \begingroup \catcode`\{=1 \catcode`\}=2 -\def\x{\everyjob{\luabytecode2}} -\expandafter\endgroup\x -\let\savedversionofeTeXversion\eTeXversion -\let\savedversionofdump\dump -\let\dump\relax -\let\eTeXversion\relax +\global\chardef\eTeXversion=2 +\global\def\eTeXrevision{.2} +\endgroup +% \let\savedversionofdump\dump +% \let\dump\relax \input latex.ltx -\let\eTeXversion\savedversionofeTeXversion -% \input luametalatex-baseregisters -\let\dump\savedversionofdump -\let\savedversionofdump\undefined -\directlua{fixupluafunctions()}% -\everyjob\expandafter{\the\everyjob\directlua{fixupluafunctions()}}% -\directlua{fixupluafunctions()}% -\dump \endinput