summaryrefslogtreecommitdiff
path: root/support/make4ht/make4ht-lib.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/make4ht/make4ht-lib.lua
Initial commit
Diffstat (limited to 'support/make4ht/make4ht-lib.lua')
-rw-r--r--support/make4ht/make4ht-lib.lua226
1 files changed, 226 insertions, 0 deletions
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()
+--]]