local lua_call_cmd = token.command_id'lua_call' local properties = node.direct.get_properties_table() node.direct.properties = properties function node.direct.get_properties_table() return properties end -- setmetatable(node.direct.get_properties_table(), { -- __index = function(t, id) -- local new = {} -- t[id] = new -- return new -- end -- }) local new_whatsit = require'luametalatex-whatsits'.new local whatsit_id = node.id'whatsit' local spacer_cmd, relax_cmd = token.command_id'spacer', token.command_id'relax' local function scan_filename() local name = {} local quoted = false local tok, cmd repeat tok = token.scan_token() cmd = tok.command until cmd ~= spacer_cmd and cmd ~= relax_cmd while (tok.command <= 12 and tok.command > 0 and tok.command ~= 9 and tok.index <= token.biggest_char() or (token.put_next(tok) and false)) and (quoted or tok.index ~= string.byte' ') do if tok.index == string.byte'"' then quoted = not quoted else name[#name+1] = tok.index end tok = token.scan_token() end return utf8.char(table.unpack(name)) end local l = lpeg or require'lpeg' local add_file_extension = l.Cs((1-('.' * (1-l.S'./\\')^0) * -1)^0 * (l.P(1)^1+l.Cc'.tex')) local ofiles = {} local function do_openout(p) if ofiles[p.file] then error[[Existing file]] else local msg ofiles[p.file], msg = io.open(add_file_extension:match(p.name), 'w') if not ofiles[p.file] then error(msg) end end end local open_whatsit = new_whatsit('open', do_openout) token.luacmd("openout", function(_, immediate) -- \openout local file = token.scan_int() token.scan_keyword'=' local name = scan_filename() local props = {file = file, name = name} if immediate == "immediate" then do_openout(props) else local whatsit = node.direct.new(whatsit_id, open_whatsit) properties[whatsit] = props node.direct.write(whatsit) end end, "protected") local function do_closeout(p) if ofiles[p.file] then ofiles[p.file]:close() ofiles[p.file] = nil end end local close_whatsit = new_whatsit('close', do_closeout) token.luacmd("closeout", function(_, immediate) -- \closeout local file = token.scan_int() local props = {file = file} if immediate == "immediate" then do_closeout(props) else local whatsit = node.direct.new(whatsit_id, close_whatsit) properties[whatsit] = props node.direct.write(whatsit) end end, "protected") local function do_write(p) local content = token.to_string(p.data) .. '\n' local file = ofiles[p.file] if file then file:write(content) else texio.write_nl(p.file < 0 and "log" or "term and log", content) end end local write_whatsit = new_whatsit('write', do_write) token.luacmd("write", function(_, immediate) -- \write local file = token.scan_int() local content = token.scan_tokenlist() local props = {file = file, data = content} if immediate == "immediate" then do_write(props) else local whatsit = node.direct.new(whatsit_id, write_whatsit) properties[whatsit] = props node.direct.write(whatsit) end end, "protected") local late_lua_whatsit = new_whatsit('late_lua', function(p, pfile, n, x, y) local code = p.data if not code then code = token.to_string(p.token) end if type(code) == 'string' then code = assert(load(code, nil, 't')) elseif not code then error[[Missing code in latelua]] end return pdf._latelua(pfile, x, y, code) end) token.luacmd("latelua", function(_) -- \latelua local content = token.scan_tokenlist() local props = {token = content} local whatsit = node.direct.new(whatsit_id, late_lua_whatsit) properties[whatsit] = props node.direct.write(whatsit) end, "protected") local functions = lua.get_functions_table() 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 return functions[function_id](function_id, 'immediate') end, "protected") require'luametalatex-baseregisters' require'luametalatex-back-pdf' require'luametalatex-node-luaotfload' local integer_code do local value_values = token.values'value' for i=0,#value_values do if value_values[i] == "integer" then integer_code = i break end end end token.luacmd("Umathcodenum", function(_, scanning) if scanning then local class, family, char = tex.getmathcodes (token.scan_int()) return integer_code, char | (class | family << 3) << 21 else local char = token.scan_int() local mathcode = token.scan_int() tex.setmathcodes(char, (mathcode >> 21) & 7, mathcode >> 24, mathcode & 0x1FFFFF) end end, "force", "global", "value")