From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/make4ht/make4ht-lib.lua | 226 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 support/make4ht/make4ht-lib.lua (limited to 'support/make4ht/make4ht-lib.lua') diff --git a/support/make4ht/make4ht-lib.lua b/support/make4ht/make4ht-lib.lua new file mode 100644 index 0000000000..2ada398f86 --- /dev/null +++ b/support/make4ht/make4ht-lib.lua @@ -0,0 +1,226 @@ +-- Simple make system for tex4ht +--kpse.set_program_name("luatex") +-- module(...,package.seeall) +local m = {} + +Make = {} +--Make.params = {} +Make.build_seq = {} +-- Patterns for matching output filenames +Make.matches = {} +Make.image_patterns = {} +Make.run_count = {} + +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; print("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 + print("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 + print("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 + print("Execute: " .. run) + return os.execute(run) + end + return false, "parse_lg: Command is not string or function" +end + +Make.image = function(self, pattern, command, params) + local tab = { + pattern = pattern, + command = command, + params = params + } + table.insert(self.image_patterns, tab) +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 + print("Make4ht convert: "..c) + os.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 + print(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 + print ("Make4ht: ".. command .." can be executed only "..repetition .."x") + else + print("Make4ht: " .. command) + local status = os.execute(command) + table.insert(return_codes,{name=v.name,status=status}) + end + else + print("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" + print("Make4ht: 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 lgfile then + self.lgfile = self.lgfile or mkutils.parse_lg(lgfile) + 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 + print("No lg file. tex4ht run failed?") + end + return return_codes +end + +m.Make = Make + +return m + +--[[Make:add("hello", "hello ${world}", {world = "world"}) +Make:add("ajaj", "ajaj") +Make:hello() +Make:hello{world="světe"} +Make:hello() +Make:run() +--]] -- cgit v1.2.3