Make.add = function(self,name,fn,par,rep)
local par = par or {}
self.params = self.params or {}
Make[name] = function(self,p,typ)
local params = {}
for k,v in pairs(self.params) do params[k] = v end
for k,v in pairs(par) do params[k] = v; log:info("setting param "..k) end
local typ = typ or "make"
local p = p or {}
local fn = fn
for k,v in pairs(p) do
params[k]=v
log:info("Adding: ",k,v)
end
-- print( fn % params)
local command = {
name=name,
type=typ,
command = fn,
params = params,
repetition = rep
}
table.insert(self.build_seq,command)
end
end
Make.length = function(self)
return #self.build_seq
end
Make.match = function(self, pattern, command, params)
local params = params or {}
table.insert(self.matches,{pattern = pattern, command = command, params = params})
end
Make.run_command = function(self,filename,s)
local command = s.command
local params = s.params
params["filename"] = filename
log:info("parse_lg process file: "..filename)
--for k,v in pairs(params) do print(k..": "..v) end
if type(command) == "function" then
return command(filename,params)
elseif type(command) == "string" then
local run = command % params
log:info("Execute: " .. run)
return mkutils.execute(run)
end
return false, "parse_lg: Command is not string or function"
end
Make.image_convert = function(self, images)
local image_patterns = self.image_patterns or {}
for i, r in pairs(image_patterns) do
local p = self.params or {}
local v = r.params or {}
for k,v in pairs(v) do
p[k]= v
end
image_patterns[i].params = p
end
for _,i in ipairs(images) do
local output = i.output
for _, x in ipairs(image_patterns) do
local pattern = x.pattern
if output:match(pattern) then
local command = x.command
local p = x.params or {}
p.output = output
p.page= i.page
p.source = i.source
if type(command) == "function" then
command(p)
elseif type(command) == "string" then
local c = command % p
log:info("Make4ht convert: "..c)
mkutils.execute(c)
end
break
end
end
end
end
Make.file_matches = function(self, files)
local statuses = {}
-- First make params for all matchers
for k,v in ipairs(self.matches) do
local v = self.matches[k].params or {}
local p = self.params or {}
for i,j in pairs(p) do
v[i] = j
end
self.matches[k].params = v
end
-- Loop over files, run command on matched
for _, file in ipairs(files)do
statuses[file] = {}
for _, s in ipairs(self.matches) do
local pattern= s.pattern
if file:match(pattern) then
local status, msg = self:run_command(file,s)
msg = msg or "No message given"
table.insert(statuses[file],status)
if status == false then
log:info(msg)
break
end
end
end
end
return statuses
end
-- add files from the mk4 file
-- we must add them to the table generated from the lg file, so they can be processed later
--
Make.add_file = function(self, filename)
-- self.lgfile should be present, as it is created once the lg_file was parsed for the first time
local lg = self.lgfile or {}
local files = lg.files or {}
-- run filters on the file
local filtertable = {filename}
-- should we care about return status?
self:file_matches(filtertable)
-- break if the file is present already
-- start at the end, it it was added by a build file, the file will be likely at the end
for i = #files,1,-1 do
if files[i] == filename then return false, "File was already added" end
end
-- save the added file to the lg_file
table.insert(lg.files, filename)
self.lg = lg
end
Make.run = function(self)
local return_codes = {}
local params = self.params or {}
for _,v in ipairs(self.build_seq) do
--print("sekvence: "..v.name)
for p,n in pairs(v.params) do params[p] = n end
--for c,_ in pairs(params) do print("build param: "..c) end
if type(v.command)=="function" then
table.insert(return_codes,{name=v.name,status = v.command(params)})
elseif type(v.command) =="string" then
local command = v.command % params
-- Some commands should be executed only limited times, typicaly once
-- tex4ht or t4ht for example
local run_count = self.run_count[v.command] or 0
run_count = run_count + 1
self.run_count[v.command] = run_count
local repetition = v.repetition
if repetition and run_count > repetition then
log:warning (command .." can be executed only "..repetition .."x")
else
log:info("executing: " .. command)
local status = mkutils.execute(command)
table.insert(return_codes,{name=v.name,status=status})
end
else
log:warning("Unknown command type, must be string or function - " ..v.name..": "..type(v.command))
end
local correct_exit = params.correct_exit or nil
if correct_exit then
local last_return = return_codes[#return_codes] or {}
local current_status = last_return.status or 0
if current_status ~= correct_exit then
local last_name = last_return.name or "unknown"
log:fatal("Fatal error. Command "..last_name .." returned exit code "..current_status)
os.exit(1)
end
end
end
local lgfile = params.input and params.input .. ".lg" or nil
if params.builddir~="" then
lgfile = params.builddir .. "/" .. lgfile
end
if lgfile then
self.lgfile = self.lgfile or mkutils.parse_lg(lgfile, params.builddir)
local lg = self.lgfile
-- First convert images from lg files
self:image_convert(lg["images"])
-- Then run file matchers on lg files and converted images
local files = lg["files"]
for _,v in ipairs(lg["images"]) do
local v = v.output
-- print(v)
table.insert(files,v)
end
self:file_matches(files)
else
log:warning("No lg file. tex4ht run failed?")
end
return return_codes
end