2021-05-31 12:42:51 +02:00
|
|
|
#!/usr/bin/env texlua
|
|
|
|
require'pdfmml-emulate-node'
|
2021-05-30 03:29:50 +02:00
|
|
|
local convert = require'luamml-convert'
|
|
|
|
local mappings = require'luamml-legacy-mappings'
|
|
|
|
local to_xml = require'luamml-xmlwriter'
|
2021-06-02 21:14:10 +02:00
|
|
|
|
2021-05-31 12:42:51 +02:00
|
|
|
local parse_showlists = require'pdfmml-showlists'
|
|
|
|
local parse_log = require'pdfmml-logreader'
|
2021-05-29 12:39:24 +02:00
|
|
|
|
2021-06-02 21:14:10 +02:00
|
|
|
local attributes = lfs.attributes
|
|
|
|
local function try_extensions_(base, extension, ...)
|
|
|
|
if extension == nil then return end
|
|
|
|
local fullname = base .. extension
|
|
|
|
if attributes(fullname, 'mode') == 'file' then
|
|
|
|
return fullname
|
|
|
|
end
|
|
|
|
return try_extensions_(base, ...)
|
|
|
|
end
|
|
|
|
local function try_extensions(base, ...)
|
|
|
|
if attributes(base, 'mode') == 'file' then return base end
|
|
|
|
return try_extensions_(base, ...)
|
|
|
|
end
|
|
|
|
|
2021-05-31 12:42:51 +02:00
|
|
|
if #arg < 1 then
|
2021-06-02 21:14:10 +02:00
|
|
|
io.stderr:write(string.format('Usage: %s {logname} [{outname}]\n\z
|
|
|
|
If {outname} includes {}, then a separate file is written for every formula with {} replaced by the formula id.\n', arg[0]))
|
2021-05-31 12:42:51 +02:00
|
|
|
os.exit(1)
|
|
|
|
end
|
2021-06-03 17:06:01 +02:00
|
|
|
local parsed = assert(parse_log(assert(try_extensions(arg[1], '.tml', '.log'),
|
2021-06-02 21:14:10 +02:00
|
|
|
"Couldn't find input file.")))
|
2021-05-29 12:39:24 +02:00
|
|
|
|
2021-06-03 17:06:01 +02:00
|
|
|
for i, inst in ipairs(parsed.instructions) do
|
|
|
|
local _, _, family, mapping_name = inst:find'^REGISTER_MAPPING:([0-9]+):(.*)$'
|
|
|
|
if family then
|
|
|
|
local mapping = mappings[mapping_name]
|
|
|
|
if mapping then
|
|
|
|
convert.register_family(tonumber(family), mapping)
|
|
|
|
else
|
|
|
|
io.stderr:write(string.format('Unknown mapping %s ignored\n', mapping_name))
|
|
|
|
end
|
|
|
|
else
|
|
|
|
io.stderr:write'Unknown instruction ignored\n'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-06-02 21:14:10 +02:00
|
|
|
local out_prefix, out_suffix, out_stream
|
|
|
|
if not arg[2] or arg[2] == '-' then
|
|
|
|
out_stream = io.stdout
|
|
|
|
else
|
|
|
|
local _ _, _, out_prefix, out_suffix = arg[2]:find'^(.*){}(.*)$'
|
|
|
|
if not out_prefix then
|
|
|
|
out_stream = assert(io.open(arg[2], 'w'))
|
|
|
|
end
|
|
|
|
end
|
2021-06-26 19:49:28 +02:00
|
|
|
parsed.mathml = {}
|
|
|
|
|
|
|
|
local function shallow_copy(t)
|
|
|
|
local new = {}
|
|
|
|
for k, v in next, t do
|
|
|
|
new[k] = v
|
|
|
|
end
|
|
|
|
return new
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Currently only 3 flag values are supported:
|
|
|
|
-- 0: Ignore (Doesn't make a lot of sense here)
|
|
|
|
-- 1: Only save
|
|
|
|
-- 3: Generate normally
|
2021-06-03 17:06:01 +02:00
|
|
|
for i, block in ipairs(parsed.groups) do
|
2021-06-27 00:43:30 +02:00
|
|
|
local flag, tag, label = block.flag, block.tag, block.label
|
2021-05-30 03:29:50 +02:00
|
|
|
block = block[1]
|
2021-06-26 19:49:28 +02:00
|
|
|
if flag & 3 ~= 0 then
|
|
|
|
local style = block.display and 0 or 2
|
|
|
|
local xml = convert.process(parse_showlists(block, nil, nil, parsed), style)
|
|
|
|
if flag & 2 == 2 then
|
|
|
|
local stream = out_stream or assert(io.open(out_prefix .. tostring(i) .. out_suffix, 'w'))
|
|
|
|
stream:write(to_xml(convert.make_root(shallow_copy(xml), style)), '\n')
|
|
|
|
if not out_stream then stream:close() end
|
|
|
|
end
|
|
|
|
if tag ~= 'mrow' then
|
|
|
|
if xml[0] == 'mrow' then
|
|
|
|
xml[0] = tag
|
|
|
|
else
|
|
|
|
xml = {[0] = tag, xml}
|
|
|
|
end
|
|
|
|
end
|
2021-06-27 04:30:49 +02:00
|
|
|
if style == 2 and flag & 1 == 1 and label then
|
2021-06-27 00:43:30 +02:00
|
|
|
if parsed.mathml[label] then
|
|
|
|
error'Invalid label reuse'
|
|
|
|
end
|
|
|
|
parsed.mathml[label] = xml
|
2021-06-26 19:49:28 +02:00
|
|
|
end
|
|
|
|
end
|
2021-05-30 03:29:50 +02:00
|
|
|
end
|