2020-05-28 14:37:19 +02:00
|
|
|
local lua_call_cmd = token.command_id'lua_call'
|
2020-01-02 04:14:39 +01:00
|
|
|
local properties = node.direct.get_properties_table()
|
2020-05-31 09:30:49 +02:00
|
|
|
node.direct.properties = properties
|
2020-06-02 01:22:59 +02:00
|
|
|
function node.direct.get_properties_table()
|
|
|
|
return properties
|
|
|
|
end
|
2019-07-17 21:14:34 +02:00
|
|
|
-- setmetatable(node.direct.get_properties_table(), {
|
|
|
|
-- __index = function(t, id)
|
|
|
|
-- local new = {}
|
|
|
|
-- t[id] = new
|
|
|
|
-- return new
|
|
|
|
-- end
|
|
|
|
-- })
|
|
|
|
|
2020-07-01 19:47:25 +02:00
|
|
|
local new_whatsit = require'luametalatex-whatsits'.new
|
2019-07-17 21:14:34 +02:00
|
|
|
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
|
2020-07-08 16:50:45 +02:00
|
|
|
while (tok.command <= 12 and tok.command > 0 and tok.command ~= 9 and tok.index <= token.biggest_char()
|
2019-07-17 21:14:34 +02:00
|
|
|
or (token.put_next(tok) and false))
|
2020-07-07 16:52:06 +02:00
|
|
|
and (quoted or tok.index ~= string.byte' ') do
|
|
|
|
if tok.index == string.byte'"' then
|
2019-07-17 21:14:34 +02:00
|
|
|
quoted = not quoted
|
|
|
|
else
|
2020-07-07 16:52:06 +02:00
|
|
|
name[#name+1] = tok.index
|
2019-07-17 21:14:34 +02:00
|
|
|
end
|
|
|
|
tok = token.scan_token()
|
|
|
|
end
|
|
|
|
return utf8.char(table.unpack(name))
|
|
|
|
end
|
|
|
|
|
2020-07-08 16:50:45 +02:00
|
|
|
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'))
|
2019-07-17 21:14:34 +02:00
|
|
|
local ofiles = {}
|
|
|
|
local function do_openout(p)
|
|
|
|
if ofiles[p.file] then
|
|
|
|
error[[Existing file]]
|
|
|
|
else
|
|
|
|
local msg
|
2020-07-08 16:50:45 +02:00
|
|
|
ofiles[p.file], msg = io.open(add_file_extension:match(p.name), 'w')
|
2019-07-17 21:14:34 +02:00
|
|
|
if not ofiles[p.file] then
|
|
|
|
error(msg)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-07-01 19:47:25 +02:00
|
|
|
local open_whatsit = new_whatsit('open', do_openout)
|
2019-07-17 23:55:11 +02:00
|
|
|
token.luacmd("openout", function(_, immediate) -- \openout
|
2019-07-17 21:14:34 +02:00
|
|
|
local file = token.scan_int()
|
|
|
|
token.scan_keyword'='
|
|
|
|
local name = scan_filename()
|
2020-07-01 19:47:25 +02:00
|
|
|
local props = {file = file, name = name}
|
2019-07-17 21:14:34 +02:00
|
|
|
if immediate == "immediate" then
|
|
|
|
do_openout(props)
|
|
|
|
else
|
2020-07-01 19:47:25 +02:00
|
|
|
local whatsit = node.direct.new(whatsit_id, open_whatsit)
|
2019-07-17 21:14:34 +02:00
|
|
|
properties[whatsit] = props
|
2020-01-02 04:14:39 +01:00
|
|
|
node.direct.write(whatsit)
|
2019-07-17 21:14:34 +02:00
|
|
|
end
|
2019-07-17 23:55:11 +02:00
|
|
|
end, "protected")
|
2019-07-17 21:14:34 +02:00
|
|
|
local function do_closeout(p)
|
|
|
|
if ofiles[p.file] then
|
|
|
|
ofiles[p.file]:close()
|
|
|
|
ofiles[p.file] = nil
|
|
|
|
end
|
|
|
|
end
|
2020-07-01 19:47:25 +02:00
|
|
|
local close_whatsit = new_whatsit('close', do_closeout)
|
2019-07-17 23:55:11 +02:00
|
|
|
token.luacmd("closeout", function(_, immediate) -- \closeout
|
2019-07-17 21:14:34 +02:00
|
|
|
local file = token.scan_int()
|
2020-07-01 19:47:25 +02:00
|
|
|
local props = {file = file}
|
2019-07-17 21:14:34 +02:00
|
|
|
if immediate == "immediate" then
|
|
|
|
do_closeout(props)
|
|
|
|
else
|
2020-07-01 19:47:25 +02:00
|
|
|
local whatsit = node.direct.new(whatsit_id, close_whatsit)
|
2019-07-17 21:14:34 +02:00
|
|
|
properties[whatsit] = props
|
2020-01-02 04:14:39 +01:00
|
|
|
node.direct.write(whatsit)
|
2019-07-17 21:14:34 +02:00
|
|
|
end
|
2019-07-17 23:55:11 +02:00
|
|
|
end, "protected")
|
2019-07-17 21:14:34 +02:00
|
|
|
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
|
2020-07-01 19:47:25 +02:00
|
|
|
local write_whatsit = new_whatsit('write', do_write)
|
2019-07-17 23:55:11 +02:00
|
|
|
token.luacmd("write", function(_, immediate) -- \write
|
2019-07-17 21:14:34 +02:00
|
|
|
local file = token.scan_int()
|
|
|
|
local content = token.scan_tokenlist()
|
2020-07-01 19:47:25 +02:00
|
|
|
local props = {file = file, data = content}
|
2019-07-17 21:14:34 +02:00
|
|
|
if immediate == "immediate" then
|
|
|
|
do_write(props)
|
|
|
|
else
|
2020-07-01 19:47:25 +02:00
|
|
|
local whatsit = node.direct.new(whatsit_id, write_whatsit)
|
2019-07-17 21:14:34 +02:00
|
|
|
properties[whatsit] = props
|
2020-01-02 04:14:39 +01:00
|
|
|
node.direct.write(whatsit)
|
2019-07-17 21:14:34 +02:00
|
|
|
end
|
2019-07-17 23:55:11 +02:00
|
|
|
end, "protected")
|
2020-07-12 19:56:50 +02:00
|
|
|
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")
|
2020-05-26 19:29:58 +02:00
|
|
|
|
2020-07-04 06:27:30 +02:00
|
|
|
local functions = lua.get_functions_table()
|
2019-07-17 23:55:11 +02:00
|
|
|
token.luacmd("immediate", function() -- \immediate
|
2019-07-17 21:14:34 +02:00
|
|
|
local next_tok = token.scan_token()
|
|
|
|
if next_tok.command ~= lua_call_cmd then
|
|
|
|
return token.put_next(next_tok)
|
|
|
|
end
|
2020-07-07 16:52:06 +02:00
|
|
|
local function_id = next_tok.index
|
2020-07-01 19:47:25 +02:00
|
|
|
return functions[function_id](function_id, 'immediate')
|
2019-07-17 23:55:11 +02:00
|
|
|
end, "protected")
|
2020-07-09 17:32:42 +02:00
|
|
|
|
2020-06-28 04:52:06 +02:00
|
|
|
require'luametalatex-baseregisters'
|
2019-07-17 21:14:34 +02:00
|
|
|
require'luametalatex-back-pdf'
|
2020-05-31 09:30:49 +02:00
|
|
|
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")
|