diff options
Diffstat (limited to 'Master/texmf-dist/scripts/make4ht/mkutils.lua')
-rwxr-xr-x | Master/texmf-dist/scripts/make4ht/mkutils.lua | 249 |
1 files changed, 221 insertions, 28 deletions
diff --git a/Master/texmf-dist/scripts/make4ht/mkutils.lua b/Master/texmf-dist/scripts/make4ht/mkutils.lua index 56c413ffb43..88b456fe9da 100755 --- a/Master/texmf-dist/scripts/make4ht/mkutils.lua +++ b/Master/texmf-dist/scripts/make4ht/mkutils.lua @@ -1,6 +1,7 @@ module(...,package.seeall) local make4ht = require("make4ht-lib") +local mkparams = require("mkparams") --template engine function interp(s, tab) local tab = tab or {} @@ -223,6 +224,8 @@ env.split = split env.string = string env.table = table env.copy = copy +env.tonumber = tonumber +env.tostring = tostring env.mkdirectories = mkdirectories env.require = require env.texio = texio @@ -230,7 +233,49 @@ env.type = type env.lfs = lfs env.os = os env.io = io +env.math = math env.unicode = unicode + + +-- it is necessary to use the settings table +-- set in the Make environment by mkutils +function env.set_settings(par) + local settings = env.settings + for k,v in pairs(par) do + settings[k] = v + end +end + +-- Add a value to the current settings +function env.settings_add(par) + local settings = env.settings + for k,v in pairs(par) do + local oldval = settings[k] or "" + settings[k] = oldval .. v + end +end + +function env.get_filter_settings(name) + local settings = env.settings + -- local settings = self.params + local filters = settings.filter or {} + local filter_options = filters[name] or {} + return filter_options +end + +function env.filter_settings(name) + -- local settings = Make.params + local settings = env.settings + local filters = settings.filter or {} + local filter_options = filters[name] or {} + return function(par) + for k,v in pairs(par) do + filter_options[k] = v + end + filters[name] = filter_options + settings.filter = filters + end +end env.Font = function(s) local font_name = s["name"] if not font_name then return nil, "Cannot find font name" end @@ -239,11 +284,35 @@ 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("test","test the variables: ${tex4ht_sty_par} ${htlatex} ${input} ${config}") + +-- this function reads the LaTeX log file and tries to detect fatal errors in the compilation +local function testlogfile(par) + 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") + -- test only the end of the log file, no need to run search functions on everything + local newlen = len - 1256 + -- but the value to seek must be greater than 0 + newlen = (newlen > 0) and newlen or 0 + f:seek("set", newlen) + local text = f:read("*a") + f:close() + if text:match("No pages of output") or text:match("TeX capacity exceeded, sorry") then return 1 end + return 0 +end + + +-- Make this function available in the build files +Make.testlogfile = testlogfile --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".. + +-- template for calling LaTeX with tex4ht loaded +Make.latex_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".. @@ -252,46 +321,170 @@ env.Make:add("htlatex",function(par) "\\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 ${tex_file}'" +"\\input ${tex_file}'" + +env.Make:add("htlatex",function(par) + local command = Make.latex_command 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 - 1256) - local text = f:read("*a") - f:close() - if text:match("No pages of output") or text:match("TeX capacity exceeded, sorry") then return 1 end - return 0 + return testlogfile(par) end ,{correct_exit=0}) + + +env.Make:add("latexmk", function(par) + local command = Make.latex_command + par.expanded = command % par + -- quotes in latex_command must be escaped, they cause Latexmk error + par.expanded = par.expanded:gsub('"', '\\"') + local newcommand = 'latexmk -latex="${expanded}" ${tex_file}' % par + os.execute(newcommand) + return Make.testlogfile(par) +end, {correct_exit= 0}) + + + env.Make:add("tex4ht","tex4ht ${tex4ht_par} \"${input}.${dvi}\"", nil, 1) env.Make:add("t4ht","t4ht ${t4ht_par} \"${input}.${ext}\"",{ext="dvi"},1) +-- enable extension in the config file +-- the following two functions must be here and not in make4ht-lib.lua +-- because of the access to env.settings +env.Make.enable_extension = function(self,name) + table.insert(env.settings.extensions, {type="+", name=name}) +end + +-- disable extension in the config file +env.Make.disable_extension = function(self,name) + table.insert(env.settings.extensions, {type="-", name=name}) +end + function load_config(settings, config_name) - local settings = settings or main_settings - env.settings = settings - env.mode = settings.mode - local config_name = kpse.find_file(config_name, 'texmfscripts') or config_name - local f = io.open(config_name,"r") - if not f then + local settings = settings or main_settings + env.settings = settings + env.mode = settings.mode + if config_name and not file_exists(config_name) then + config_name = kpse.find_file(config_name, 'texmfscripts') or config_name + end + local f = io.open(config_name,"r") + if not f then print("Cannot open config file", config_name) return env end print("Using build file", config_name) - local code = f:read("*all") - local fn, msg = run(code,env) - if not fn then print(msg) end - assert(fn) - return env + local code = f:read("*all") + local fn, msg = run(code,env) + if not fn then print(msg) end + assert(fn) + return env +end + +local function find_lua_file(name) + local extension_path = name:gsub("%.", "/") .. ".lua" + return kpse.find_file(extension_path, "lua") +end + +--- load the output format plugins +function load_output_format(format_name) + local format_library = "make4ht.formats."..format_name + local is_format_file = find_lua_file(format_library) + if is_format_file then + local format = assert(require(format_library)) + if format then + format.prepare_extensions = format.prepare_extensions or function(extensions) return extensions end + end + return format + end +end + +--- Execute the prepare_parameters function in list of extensions +function extensions_prepare_parameters(extensions, parameters) + for _, ext in ipairs(extensions) do + -- execute the extension only if it contains prepare_parameters function + local fn = ext.prepare_parameters + if fn then + parameters = fn(parameters) + end + end + return parameters +end + +--- Modify the build sequence using extensions +-- @param extensions list of extensions +-- @make Make object +function extensions_modify_build(extensions, make) + for _, ext in ipairs(extensions) do + local fn = ext.modify_build + if fn then + make = fn(make) + end + end + return make +end + + +--- load one extension +-- @param name extension name +-- @param format current output format +function load_extension(name,format) + -- first test if the extension exists + local extension_library = "make4ht.extensions." .. name + local is_extension_file = find_lua_file(extension_library) + -- don't try to load the extension if it doesn't exist + if not is_extension_file then return nil end + local extension = require("make4ht.extensions.".. name) + -- extensions can test if the current output format is supported + local test = extension.test + if test then + if test(format) then + return extension + end + -- if the test fail return nil + return nil + end + -- if the extension doesn't provide the test function, we will assume that + -- it supports every output format + return extension end +--- load extensions +-- @param extensions table created by mkparams.get_format_extensions function +-- @param format output type format. extensions may support only certain file +-- formats +function load_extensions(extensions, format) + local module_names = {} + local extension_table = {} + -- process the extension table. it contains type field, which can enable or + -- diable the extension + for _, v in ipairs(extensions) do + local enable = v.type == "+" and true or nil + module_names[v.name] = enable + end + for name, _ in pairs(module_names) do + local extension = load_extension(name,format) + if extension then + table.insert(extension_table, extension) + else + print("Cannot load extension: ".. name) + end + end + return extension_table +end + +--- add new extensions to a list of loaded extensions +-- @param added string with extensions to be added in the form +ext1+ext2 +function add_extensions(added, extensions) + local _, newextensions = mkparams.get_format_extensions("dummyfmt" .. added) + -- insert new extension at the beginning, in order to support disabling using + -- the -f option + for _, x in ipairs(extensions or {}) do table.insert(newextensions, x) end + return newextensions +end +-- I don't know if this is clean, but settings functions won't be available +-- for filters and extensions otherwise +for k,v in pairs(env) do _G[k] = v end |