summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/make4ht/mkutils.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/scripts/make4ht/mkutils.lua')
-rwxr-xr-xMaster/texmf-dist/scripts/make4ht/mkutils.lua290
1 files changed, 290 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/make4ht/mkutils.lua b/Master/texmf-dist/scripts/make4ht/mkutils.lua
new file mode 100755
index 00000000000..ca9e2ff208a
--- /dev/null
+++ b/Master/texmf-dist/scripts/make4ht/mkutils.lua
@@ -0,0 +1,290 @@
+module(...,package.seeall)
+
+local make4ht = require("make4ht-lib")
+--template engine
+function interp(s, tab)
+ local tab = tab or {}
+ return (s:gsub('($%b{})', function(w) return tab[w:sub(3, -2)] or w end))
+end
+--print( interp("${name} is ${value}", {name = "foo", value = "bar"}) )
+
+function addProperty(s,prop)
+ if prop ~=nil then
+ return s .." "..prop
+ else
+ return s
+ end
+end
+getmetatable("").__mod = interp
+getmetatable("").__add = addProperty
+
+--print( "${name} is ${value}" % {name = "foo", value = "bar"} )
+-- Outputs "foo is bar"
+
+function string:split(sep)
+ local sep, fields = sep or ":", {}
+ local pattern = string.format("([^%s]+)", sep)
+ self:gsub(pattern, function(c) fields[#fields+1] = c end)
+ return fields
+end
+
+function remove_extension(path)
+ local found, len, remainder = string.find(path, "^(.*)%.[^%.]*$")
+ if found then
+ return remainder
+ else
+ return path
+ end
+end
+
+--
+
+function file_exists(file)
+ local f = io.open(file, "rb")
+ if f then f:close() end
+ return f ~= nil
+end
+
+-- searching for converted images
+function parse_lg(filename)
+ print("Parse LG")
+ local outputimages,outputfiles,status={},{},nil
+ local fonts, used_fonts = {},{}
+ if not file_exists(filename) then
+ print("Cannot read log file: "..filename)
+ else
+ local usedfiles={}
+ for line in io.lines(filename) do
+ --- needs --- pokus.idv[1] ==> pokus0x.png ---
+ -- line:gsub("needs --- (.+?)[([0-9]+) ==> ([%a%d%p%.%-%_]*)",function(name,page,k) table.insert(outputimages,k)end)
+ line:gsub("needs %-%-%- (.+)%[([0-9]+)%] ==> ([%a%d%p%.%-%_]*)",
+ function(file,page,output)
+ local rec = {
+ source = file,
+ page=page,
+ output = output
+ }
+ table.insert(outputimages,rec)
+ end
+ )
+ line:gsub("File: (.*)", function(k)
+ if not usedfiles[k] then
+ table.insert(outputfiles,k)
+ usedfiles[k] = true
+ end
+ end)
+ line:gsub("htfcss: ([^%s]+)(.*)",function(k,r)
+ local fields = {}
+ r:gsub("[%s]*([^%:]+):[%s]*([^;]+);",function(c,v)
+ fields[c] = v
+ end)
+ fonts[k] = fields
+ end)
+
+ line:gsub('Font("([^"]+)","([%d]+)","([%d]+)","([%d]+)"',function(n,s1,s2,s3)
+ table.insert(used_fonts,{n,s1,s2,s3})
+ end)
+
+ end
+ status=true
+ end
+ return {files = outputfiles, images = outputimages},status
+end
+
+
+local cp_func = os.type == "unix" and "cp" or "copy"
+function cp(src,dest)
+ local command = string.format('%s %s %s', cp_func, src, dest)
+ if cp_func == "copy" then command = command:gsub("/",'\\') end
+ print("Copy: "..command)
+ os.execute(command)
+end
+
+local used_dir = {}
+
+function prepare_path(path)
+ --local dirs = path:split("/")
+ local dirs = {}
+ if path:match("^/") then dirs = {""}
+ elseif path:match("^~") then
+ local home = os.getenv "HOME"
+ dirs = home:split "/"
+ path = path:gsub("^~/","")
+ table.insert(dirs,1,"")
+ end
+ if path:match("/$")then path = path .. " " end
+ for _,d in pairs(path:split "/") do
+ table.insert(dirs,d)
+ end
+ table.remove(dirs,#dirs)
+ return dirs,table.concat(dirs,"/")
+end
+
+-- Find which part of path already exists
+-- and which directories have to be created
+function find_directories(dirs, pos)
+ local pos = pos or #dirs
+ -- we tried whole path and no dir exist
+ if pos < 1 then return dirs end
+ local path = ""
+ -- in the case of unix absolute path, empty string is inserted in dirs
+ if pos == 1 and dirs[pos] == "" then
+ path = "/"
+ else
+ path = table.concat(dirs,"/", 1,pos) .. "/"
+ end
+ if not lfs.chdir(path) then -- recursion until we succesfully changed dir
+ -- or there are no elements in the dir table
+ return find_directories(dirs,pos - 1)
+elseif pos ~= #dirs then -- if we succesfully changed dir
+ -- and we have dirs to create
+ local p = {}
+ for i = pos+1, #dirs do
+ table.insert(p, dirs[i])
+ end
+ return p
+else -- whole path exists
+ return {}
+end
+end
+
+function mkdirectories(dirs)
+ if type(dirs) ~="table" then
+ return false, "mkdirectories: dirs is not table"
+ end
+ for _,d in pairs(dirs) do
+ local stat,msg = lfs.mkdir(d)
+ if not stat then return false, "makedirectories error: "..msg end
+ lfs.chdir(d)
+ end
+ return true
+end
+
+function copy_filter(src,dest, filter)
+ local src_f=io.open(src,"rb")
+ local dst_f=io.open(dest,"w")
+ local contents = src_f:read("*all")
+ local filter = filter or function(s) return s end
+ src_f:close()
+ dst_f:write(filter(contents))
+ dst_f:close()
+end
+
+
+
+function copy(filename,outfilename)
+ local currdir = lfs.currentdir()
+ if filename == outfilename then return true end
+ local parts, path = prepare_path(outfilename)
+ if not used_dir[path] then
+ local to_create, msg = find_directories(parts)
+ if not to_create then
+ print(msg)
+ return false
+ end
+ used_dir[path] = true
+ local stat, msg = mkdirectories(to_create)
+ if not stat then print(msg) end
+ end
+ lfs.chdir(currdir)
+ cp(filename, path)
+ return true
+end
+
+-- Config loading
+local function run(untrusted_code, env)
+ if untrusted_code:byte(1) == 27 then return nil, "binary bytecode prohibited" end
+ local untrusted_function = nil
+ if not loadstring then
+ untrusted_function, message = load(untrusted_code, nil, "t",env)
+ else
+ untrusted_function, message = loadstring(untrusted_code)
+ end
+ if not untrusted_function then return nil, message end
+ if not setfenv then setfenv = function(a,b) return true end end
+ setfenv(untrusted_function, env)
+ return pcall(untrusted_function)
+end
+
+local main_settings = {}
+main_settings.fonts = {}
+local env = {}
+
+-- We make sandbox for make script, all functions must be explicitely declared
+-- Function declarations:
+env.pairs = pairs
+env.ipairs = ipairs
+env.print = print
+env.split = split
+env.string = string
+env.table = table
+env.copy = copy
+env.mkdirectories = mkdirectories
+env.require = require
+env.texio = texio
+env.type = type
+env.lfs = lfs
+env.os = os
+env.io = io
+env.unicode = unicode
+env.Font = function(s)
+ local font_name = s["name"]
+ if not font_name then return nil, "Cannot find font name" end
+ env.settings.fonts[font_name] = s
+end
+
+env.Make = make4ht.Make
+env.Make.params = env.settings
+env.Make:add("test","no takže ${tex4ht_sty_par} ${htlatex} ${input} ${config}")
+--env.Make:add("htlatex", "${htlatex} ${latex_par} '\\\makeatletter\\def\\HCode{\\futurelet\\HCode\\HChar}\\def\\HChar{\\ifx\"\\HCode\\def\\HCode\"##1\"{\\Link##1}\\expandafter\\HCode\\else\\expandafter\\Link\\fi}\\def\\Link#1.a.b.c.{\\g@addto@macro\\@documentclasshook{\\RequirePackage[#1,html]{tex4ht}\\let\\HCode\\documentstyle\\def\\documentstyle{\\let\\documentstyle\\HCode\\expandafter\\def\\csname tex4ht\\endcsname{#1,html}\\def\\HCode####1{\\documentstyle[tex4ht,}\\@ifnextchar[{\\HCode}{\\documentstyle[tex4ht]}}}\\makeatother\\HCode '${config}${tex4ht_sty_par}'.a.b.c.\\input ' ${input}")
+env.Make:add("htlatex",function(par)
+ local command =
+"${htlatex} ${latex_par} '\\makeatletter"..
+"\\def\\HCode{\\futurelet\\HCode\\HChar}\\def\\HChar{\\ifx\"\\HCode"..
+"\\def\\HCode\"##1\"{\\Link##1}\\expandafter\\HCode\\else"..
+"\\expandafter\\Link\\fi}\\def\\Link#1.a.b.c.{\\g@addto@macro"..
+"\\@documentclasshook{\\RequirePackage[#1,html]{tex4ht}${packages}}"..
+"\\let\\HCode\\documentstyle\\def\\documentstyle{\\let\\documentstyle"..
+"\\HCode\\expandafter\\def\\csname tex4ht\\endcsname{#1,html}\\def"..
+"\\HCode####1{\\documentstyle[tex4ht,}\\@ifnextchar[{\\HCode}{"..
+"\\documentstyle[tex4ht]}}}\\makeatother\\HCode ${tex4ht_sty_par}.a.b.c."..
+"\\input ${input}'"
+ if os.type == "windows" then
+ command = command:gsub("'",'')
+ end
+ command = command % par
+ print("LaTeX call: "..command)
+ os.execute(command)
+ local logfile = par.input .. ".log"
+ local f = io.open(logfile,"r")
+ if not f then
+ print("Make4ht: cannot open log file "..logfile)
+ return 1
+ end
+ local len = f:seek("end")
+
+ f:seek("set", len - 256)
+ local text = f:read("*a")
+ f:close()
+ if text:match("No pages of output") then return 1 end
+ return 0
+end
+,{correct_exit=0})
+env.Make:add("tex4ht","tex4ht ${tex4ht_par} ${input}", nil, 1)
+env.Make:add("t4ht","t4ht ${t4ht_par} ${input}.${ext}",{ext="dvi"},1)
+
+function load_config(settings, config_name)
+ local settings = settings or main_settings
+ env.settings = settings
+ env.mode = settings.mode
+ local config_name = config_name or "config.lua"
+ local f = io.open(config_name,"r")
+ if not f then return env, "Cannot open config file" end
+ local code = f:read("*all")
+ local fn, msg = run(code,env)
+ if not fn then print(msg) end
+ assert(fn)
+ return env
+end
+
+