From 8cd3bed99a3581a336526a347f925d9925ddc0d8 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 1 Nov 2019 21:03:38 +0000 Subject: tex4ebook (1nov19) git-svn-id: svn://tug.org/texlive/trunk@52604 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/scripts/tex4ebook/exec_epub.lua | 372 ++++++++++----------- Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua | 129 ++++++- Master/texmf-dist/scripts/tex4ebook/exec_mobi.lua | 3 +- Master/texmf-dist/scripts/tex4ebook/tex4ebook | 99 +++--- 4 files changed, 349 insertions(+), 254 deletions(-) (limited to 'Master/texmf-dist/scripts') diff --git a/Master/texmf-dist/scripts/tex4ebook/exec_epub.lua b/Master/texmf-dist/scripts/tex4ebook/exec_epub.lua index d92a8d103c9..24cc626aad3 100755 --- a/Master/texmf-dist/scripts/tex4ebook/exec_epub.lua +++ b/Master/texmf-dist/scripts/tex4ebook/exec_epub.lua @@ -2,6 +2,7 @@ module("exec_epub",package.seeall) local lfs = require("lfs") local os = require("os") local io = require("io") +local log = logging.new("exec_epub") --local ebookutils = require("ebookutils") local ebookutils = require "mkutils" -- font loading doesn't work, font database format changes often @@ -29,25 +30,19 @@ local function deletedir(dir) if file ~= "." and file ~= ".." then if lfs.attributes(file_path, 'mode') == 'file' then os.remove(file_path) - print('remove file',file_path) + log:info('remove file',file_path) elseif lfs.attributes(file_path, 'mode') == 'directory' then - print('dir', file_path) + log:info('dir', file_path) deletedir(file_path) end end end lfs.rmdir(dir) end - print('remove dir',dir) + log:info('remove dir',dir) end function prepare(params) - local randname=tostring(math.random(12000)) - -- if not ebookutils.file_exists("tex4ht.env") then - -- local env_file = kpse.find_file("epub2.env") - --print("Local env file: "..env_file) - -- ebookutils.copy(env_file,"tex4ht.env") - -- end local makedir= function(path) local current = lfs.currentdir() local dir = ebookutils.prepare_path(path .. "/") @@ -60,29 +55,45 @@ function prepare(params) lfs.chdir(current) end basedir = params.input.."-".. params.format - outputdir= basedir.."/"..outputdir_name --"outdir-"..randname --os.tmpdir() + outputdir= basedir.."/"..outputdir_name deletedir(basedir) makedir(outputdir) - -- lfs.mkdir(outputdir) - --ebookutils.mkdirectories(ebookutils.prepare_path(outputdir.."/")) - metadir = basedir .."/" .. metadir_name --"metadir-"..randname + metadir = basedir .."/" .. metadir_name makedir(metadir) if params.outdir ~= "" then destdir = params.outdir .. "/" makedir(destdir) end - --local dd = ebookutils.prepare_path(metadir.."/") - --for _,d in pairs(dd) do print("metadir path: "..d) end - -- lfs.mkdir(metadir) - --local status, msg = ebookutils.mkdirectories(ebookutils.prepare_path(metadir.."/")) - --if not status then print("make mmetadir error:" ..msg) end mimetype= basedir .. "/" ..mimetype_name --os.tmpname() - print(outputdir) - print(mimetype) tidy = params.tidy include_fonts = params.include_fonts params["t4ht_par"] = params["t4ht_par"] -- + "-d"..string.format(params["t4ht_dir_format"],outputdir) params.tex4ht_sty_par = params.tex4ht_sty_par .. ",uni-html4" + params.config_file.Make.params = params + local mode = params.mode + if params.config_file.Make:length() < 1 then + if mode == "draft" then + params.config_file.Make:htlatex() + else + params.config_file.Make:htlatex() + params.config_file.Make:htlatex() + params.config_file.Make:htlatex() + end + end + if #params.config_file.Make.image_patterns > 0 then + params["t4ht_par"] = params["t4ht_par"] .." -p" + end + params.config_file.Make:tex4ht() + params.config_file.Make:t4ht() + -- do some cleanup + params.config_file.Make:match("tmp$",function(filename, par) + -- detect if a tmp file was created for content from STDIN + if par.is_tmp_file then + -- and remove it + log:info("Removing temporary file", par.tex_file) + os.remove(par.tex_file) + end + end) return(params) end @@ -90,7 +101,7 @@ function run(out,params) --local currentdir= outputfilename=out outputfile = outputfilename..".epub" - print("Output file: "..outputfile) + log:info("Output file: "..outputfile) --lfs.chdir(metadir) local m= io.open(metadir.."/container.xml","w") m:write([[ @@ -107,27 +118,7 @@ media-type="application/oebps-package+xml"/> m=io.open(mimetype,"w") m:write("application/epub+zip") m:close() - local htlatex_run = "${htlatex} ${input} \"${config}${tex4ht_sty_par}\" \"${tex4ht_par}\" \"${t4ht_par}\" \"${latex_par}\"" % params - print("Make4ht run") - print("-------------------") - params.config_file.Make.params = params - local mode = params.mode - if params.config_file.Make:length() < 1 then - if mode == "draft" then - params.config_file.Make:htlatex() - else - params.config_file.Make:htlatex() - params.config_file.Make:htlatex() - params.config_file.Make:htlatex() - end - end - if #params.config_file.Make.image_patterns > 0 then - params["t4ht_par"] = params["t4ht_par"] .." -p" - end - params.config_file.Make:tex4ht() - params.config_file.Make:t4ht() params.config_file.Make:run() - print("-------------------") --[[for k,v in pairs(params.config_file.Make) do print(k.. " : "..type(v)) end--]] @@ -162,7 +153,7 @@ function make_opf() -- Find mimetype and make item tag for each converted file in the lg file local fname,ext = item:match("([%a%d%_%-]*)%p([%a%d]*)$") local mimetype = mimetypes[ext] or "" - if mimetype == "" then print("Mimetype for "..ext.." is not registered"); return nil end + if mimetype == "" then log:info("Mimetype for "..ext.." is not registered"); return nil end local dir_part = item:split("/") table.remove(dir_part,#dir_part) local id=table.concat(dir_part,"-")..fname.."_"..ext @@ -190,165 +181,164 @@ function make_opf() --local opf_second_part = outputdir .. "/content-part2.opf" if ebookutils.file_exists(opf_first_part) and ebookutils.file_exists(opf_second_part) - then - local h_first = io.open(opf_first_part,"r") - local h_second = io.open(opf_second_part,"r") - local opf_complete = {} - table.insert(opf_complete,h_first:read("*all")) - local used_html = find_all_files(opf_complete[1]) - -- local lg_file = ebookutils.parse_lg(outputfilename..".lg") - -- The lg_file has been already loaded by make4ht, it doesn't make sense to load it again - -- Furthermore, it is now possible to add new files from Lua build files - local lg_file = Make.lgfile or ebookutils.parse_lg(outputfilename..".lg") - local used_files = {} - for _,filename in ipairs(lg_file["files"]) do - -- we need to test the filenames in order to prevent duplicates - -- filenames are tested without paths, so there may be issues if - -- the same filename is used in different directories. Is that a problem? - used_files[filename] = true - end - local outside_spine = {} - local all_used_files = find_all_files(opf_complete[1],"([%a%d%-%_]+%.[%a%d]+)") - local used_paths = {} - local used_ids = {} - for _,k in ipairs(lg_file["files"]) do - local ext = k:match("%.([%a%d]*)$") - local parts = k:split "/" - local fn = parts[#parts] - local allow_in_spine = {html="",xhtml = "", xml = ""} - table.remove(parts,#parts) - --table.insert(parts,1,"OEBPS") - table.insert(parts,1,outputdir) - -- print("SSSSS "..fn.." ext .." .. ext) - --if string.find("jpg gif png", ext) and not all_used_files[k] then - local item,id = lg_item(k) - if item then - local path = table.concat(parts) - if not used_paths[path] then - ebookutils.mkdirectories(parts) - used_paths[path]=true - end - if allow_in_spine[ext] and tidy then - if tidyconf then - print("Tidy: "..k) - local run ="tidy -c -w 200 -q -utf8 -m -config " .. tidyconf .." " .. k - os.execute(run) - else - print "Tidy: Cannot load tidyconf.conf" - end - end - if not used_ids[id] then - ebookutils.copy(k, outputdir .. "/"..k) - if not all_used_files[fn] then - table.insert(opf_complete,item) - if allow_in_spine[ext] then - table.insert(outside_spine,id) - end + then + local h_first = io.open(opf_first_part,"r") + local h_second = io.open(opf_second_part,"r") + local opf_complete = {} + table.insert(opf_complete,h_first:read("*all")) + local used_html = find_all_files(opf_complete[1]) + -- local lg_file = ebookutils.parse_lg(outputfilename..".lg") + -- The lg_file has been already loaded by make4ht, it doesn't make sense to load it again + -- Furthermore, it is now possible to add new files from Lua build files + local lg_file = Make.lgfile or ebookutils.parse_lg(outputfilename..".lg") + local used_files = {} + for _,filename in ipairs(lg_file["files"]) do + -- we need to test the filenames in order to prevent duplicates + -- filenames are tested without paths, so there may be issues if + -- the same filename is used in different directories. Is that a problem? + used_files[filename] = true + end + local outside_spine = {} + local all_used_files = find_all_files(opf_complete[1],"([%a%d%-%_]+%.[%a%d]+)") + local used_paths = {} + local used_ids = {} + for _,k in ipairs(lg_file["files"]) do + local ext = k:match("%.([%a%d]*)$") + local parts = k:split "/" + local fn = parts[#parts] + local allow_in_spine = {html="",xhtml = "", xml = ""} + table.remove(parts,#parts) + --table.insert(parts,1,"OEBPS") + table.insert(parts,1,outputdir) + -- print("SSSSS "..fn.." ext .." .. ext) + --if string.find("jpg gif png", ext) and not all_used_files[k] then + local item,id = lg_item(k) + if item then + local path = table.concat(parts) + if not used_paths[path] then + ebookutils.mkdirectories(parts) + used_paths[path]=true + end + if allow_in_spine[ext] and tidy then + if tidyconf then + log:info("Tidy: "..k) + local run ="tidy -c -w 200 -q -utf8 -m -config " .. tidyconf .." " .. k + os.execute(run) + else + log:info "Tidy: Cannot load tidyconf.conf" + end + end + if not used_ids[id] then + ebookutils.copy(k, outputdir .. "/"..k) + if not all_used_files[fn] then + table.insert(opf_complete,item) + if allow_in_spine[ext] then + table.insert(outside_spine,id) end - end - used_ids[id] = true - end - end - for _,f in ipairs(lg_file["images"]) do - local f = f.output - local p, id = lg_item(f) - -- process the images only if they weren't registered in lg_file["files"] - -- they would be processed twice otherwise - if not used_files[f] and not used_ids[id] then - ebookutils.copy(f, outputdir .. "/"..f) - table.insert(opf_complete,p) + end end used_ids[id] = true - end - local end_opf = h_second:read("*all") - local spine_items = {} - for _,i in ipairs(outside_spine) do - table.insert(spine_items, - '' % {idref=i}) - end - table.insert(opf_complete,end_opf % {spine = table.concat(spine_items,"\n")}) - h_first:close() - h_second:close() - h_first = io.open(opf_first_part,"w") - local opf_completed = table.concat(opf_complete,"\n") - -- poor man's tidy: remove trailing whitespace befora xml tags - opf_completed = opf_completed:gsub("[ ]*<","<") - opf_completed = remove_empty_guide(opf_completed) - h_first:write(opf_completed) - h_first:close() - os.remove(opf_second_part) - --ebookutils.copy(outputfilename ..".css",outputdir.."/") - ebookutils.copy(opf_first_part,outputdir.."/"..opf_first_part) - --for c,v in pairs(lg_file["fonts"]) do - -- print(c, table.concat(v,", ")) - --end - --print(table.concat(opf_complete,"\n")) - else - print("Missing opf file") - end - end - local function find_zip() - if io.popen("zip -v","r"):close() then - return "zip" - elseif io.popen("miktex-zip -v","r"):close() then - return "miktex-zip" + end + end + for _,f in ipairs(lg_file["images"]) do + local f = f.output + local p, id = lg_item(f) + -- process the images only if they weren't registered in lg_file["files"] + -- they would be processed twice otherwise + if not used_files[f] and not used_ids[id] then + ebookutils.copy(f, outputdir .. "/"..f) + table.insert(opf_complete,p) + end + used_ids[id] = true + end + local end_opf = h_second:read("*all") + local spine_items = {} + for _,i in ipairs(outside_spine) do + table.insert(spine_items, + '' % {idref=i}) end - print "It appears you don't have zip command installed. I can't pack the ebook" + table.insert(opf_complete,end_opf % {spine = table.concat(spine_items,"\n")}) + h_first:close() + h_second:close() + h_first = io.open(opf_first_part,"w") + local opf_completed = table.concat(opf_complete,"\n") + -- poor man's tidy: remove trailing whitespace befora xml tags + opf_completed = opf_completed:gsub("[ ]*<","<") + opf_completed = remove_empty_guide(opf_completed) + h_first:write(opf_completed) + h_first:close() + os.remove(opf_second_part) + --ebookutils.copy(outputfilename ..".css",outputdir.."/") + ebookutils.copy(opf_first_part,outputdir.."/"..opf_first_part) + --for c,v in pairs(lg_file["fonts"]) do + -- print(c, table.concat(v,", ")) + --end + --print(table.concat(opf_complete,"\n")) + else + log:warning("Missing opf file") + end +end +local function find_zip() + if io.popen("zip -v","r"):close() then return "zip" + elseif io.popen("miktex-zip -v","r"):close() then + return "miktex-zip" end + log:warning "It appears you don't have zip command installed. I can't pack the ebook" + return "zip" +end - function pack_container() - local ncxfilename = outputdir .. "/" .. outputfilename .. ".ncx" - if os.execute("tidy -v") > 0 then - print("Warning:\n tidy command seems missing, you should install it" .. - " in order\n to make valid epub file") - print("Using regexp based cleaning") - local lines = {} - for line in io.lines(ncxfilename) do - local content = line:gsub("[ ]*<","<") - if content:len() > 0 then - table.insert(lines, content) - end +function pack_container() + local ncxfilename = outputdir .. "/" .. outputfilename .. ".ncx" + if os.execute("tidy -v") > 0 then + log:warning("tidy command seems missing, you should install it" .. + " in order\n to make valid epub file") + log:info("Using regexp based cleaning") + local lines = {} + for line in io.lines(ncxfilename) do + local content = line:gsub("[ ]*<","<") + if content:len() > 0 then + table.insert(lines, content) end - table.insert(lines,"") - local ncxfile = io.open(ncxfilename,"w") - ncxfile:write(table.concat(lines,"\n")) - ncxfile:close() - else - print("Tidy ncx ".. - os.execute("tidy -xml -i -q -utf8 -m " .. ncxfilename)) - print("Tidy opf ".. - os.execute("tidy -xml -i -q -utf8 -m " .. - outputdir .. "/" .. "content.opf")) - end - print(mimetype) - local zip = find_zip() - -- we need to remove the epub file if it exists already, because it may contain files which aren't used anymore - if ebookutils.file_exists(outputfile) then os.remove(outputfile) end - print("Pack mimetype " .. os.execute("cd "..basedir.." && "..zip.." -q0X "..outputfile .." ".. mimetype_name)) - print("Pack metadir " .. os.execute("cd "..basedir.." && "..zip.." -qXr9D " .. outputfile.." "..metadir_name)) - print("Pack outputdir " .. os.execute("cd "..basedir.." && "..zip.." -qXr9D " .. outputfile.." "..outputdir_name)) - print("Copy generated epub ") - ebookutils.cp(basedir .."/"..outputfile, destdir .. outputfile) + end + table.insert(lines,"") + local ncxfile = io.open(ncxfilename,"w") + ncxfile:write(table.concat(lines,"\n")) + ncxfile:close() + else + log:info("Tidy ncx ".. + os.execute("tidy -xml -i -q -utf8 -m " .. ncxfilename)) + log:info("Tidy opf ".. + os.execute("tidy -xml -i -q -utf8 -m " .. + outputdir .. "/" .. "content.opf")) + end + local zip = find_zip() + -- we need to remove the epub file if it exists already, because it may contain files which aren't used anymore + if ebookutils.file_exists(outputfile) then os.remove(outputfile) end + log:info("Pack mimetype " .. os.execute("cd "..basedir.." && "..zip.." -q0X "..outputfile .." ".. mimetype_name)) + log:info("Pack metadir " .. os.execute("cd "..basedir.." && "..zip.." -qXr9D " .. outputfile.." "..metadir_name)) + log:info("Pack outputdir " .. os.execute("cd "..basedir.." && "..zip.." -qXr9D " .. outputfile.." "..outputdir_name)) + log:info("Copy generated epub ") + ebookutils.cp(basedir .."/"..outputfile, destdir .. outputfile) end - function writeContainer() - make_opf() - pack_container() - end - local function deldir(path) - for entry in lfs.dir(path) do - if entry~="." and entry~=".." then - os.remove(path.."/"..entry) - end - end - os.remove(path) - --]] - end +function writeContainer() + make_opf() + pack_container() +end +local function deldir(path) + for entry in lfs.dir(path) do + if entry~="." and entry~=".." then + os.remove(path.."/"..entry) + end + end + os.remove(path) + --]] +end - function clean() - --deldir(outputdir) - --deldir(metadir) - --os.remove(mimetype) +function clean() + --deldir(outputdir) + --deldir(metadir) + --os.remove(mimetype) end diff --git a/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua b/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua index 53173be9e9c..edf6df01c22 100755 --- a/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua +++ b/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua @@ -1,6 +1,7 @@ module(...,package.seeall) local eb = require("exec_epub") local dom = require("luaxml-domobject") +local log = logging.new "exec_epub3" local ext = "xhtml" local outputdir = nil @@ -60,7 +61,10 @@ local function add_media_overlays(content) end return os.date("%H:%M:%S",time) end - local opfdom = dom.parse(content) + -- the second parameter for parse is table with void elements. the OPF format has no + -- void elements, so it needs to be empty, otherwise we may get parsing error because of + -- element, which is included in the default void elements + local opfdom = dom.parse(content, {}) local items = opfdom:query_selector("manifest item") local ref = {} local times = {} @@ -109,23 +113,136 @@ local function add_media_overlays(content) end +local function remove_spurious_TOC_elements(tocdom) + local function count_child_elements(el) + -- count children elements of the current element + local count = 0 + for _, curr_el in ipairs(el:get_children()) do + if curr_el:is_element() then count = count + 1 end + end + return count + end + -- modify the TOC to comply to epubcheck tests + -- add a blank
  • to empty
      + for _, el in ipairs(tocdom:query_selector("ol")) do + if count_child_elements(el) == 0 then + el:remove_node() + -- local newli = el:create_element("li") + -- local newspan = newli:create_element("span") + -- newli:add_child_node(newspan) + -- el:add_child_node(newli) + end + end + -- place child elements of the
    1. elements to an element, epubcheck reports + -- error for text nodes that are direct child of
    2. + for _, el in ipairs(tocdom:query_selector("li")) do + local text = {} + local link -- save the element + for i, child in ipairs(el._children) do + if child:is_text() then + -- trim spurious spaces + local childtext = child._text:gsub("^%s*",""):gsub("%s*$","") + -- save the text for the later use + table.insert(text, childtext) + child:remove_node() + elseif child:is_element() and child:get_element_name() == "a" then + link = child + table.insert(text, child:get_text()) + end + end + if link then + local content = table.concat(text, " ") + -- remove the original text + link._children = {} + local text = link:create_text_node(content) + link:add_child_node(text) + end + end + return tocdom + +end +local function cleanTOC(content) + -- remove spurious empty elements from the TOC, to make epubcheck happy + -- find the file with TOC ("properties" attribute set to "nav" + local opfdom = dom.parse(content,{}) + for _,item in ipairs(opfdom:query_selector("item")) do + local properties = item:get_attribute("properties") or "" + if properties:match("nav") then + local filename = item:get_attribute("href") + if filename then + filename = outputdir .. "/" .. filename + local f = io.open(filename, "r") + local t = f:read("*all") + f:close() + local tocdom = dom.parse(t) + tocdom = remove_spurious_TOC_elements(tocdom) + f = io.open(filename,"w") + f:write(tocdom:serialize()) + f:close() + end + end + end + + +end + +local function fix_properties(content) + -- some properties should be used only in the element, so we need to move them + -- here from the section + -- because why it should be easy, when you can just make messy specification + -- and of course my old code is extremely messy as well. + if content:match("page%-spread%-") or content:match("rendition") then + local spread_ids = {} + local opfdom = dom.parse(content,{}) + local update_properties = function(id, s) + local current_val = spread_ids[id] or {} + current_val[#current_val + 1] = s + spread_ids[id] = current_val + return "" + end + for _,item in ipairs(opfdom:query_selector("manifest item")) do + local properties = item:get_attribute "properties" + if properties then + local id = item:get_attribute "id" + properties = properties:gsub("(page%-spread%-[^%s]+)", function(s) return update_properties(id,s) end) + properties = properties:gsub("(rendition%:[^%s]+)", function(s) return update_properties(id,s) end) + -- properties attribute cannot be empty, we must disable it if + -- it doesn't contain anything after removing of the page spread + if properties:match("^%s*$") then properties = nil + end + item:set_attribute("properties", properties) + end + end + for _, item in ipairs(opfdom:query_selector("spine itemref")) do + local idref = item:get_attribute("idref") + local spread = spread_ids[idref] + if spread then + item:set_attribute("properties", table.concat(spread, " ")) + end + end + return opfdom:serialize() + end + return content +end + local function cleanOPF() -- in epub3, there must be table of contents -- if there is no toc in the document, we must add generic one local opf = "content.opf" local f = io.open(opf,"r") if not f then - print("Cannot open "..opf .. " for toc searching") + log:info("Cannot open "..opf .. " for toc searching") return nil end local content = f:read("*all") f:close() if content:find "properties[%s]*=[%s]*\"[^\"]*nav" then - print "TOC nav found" + log:info "TOC nav found" + cleanTOC(content) else - print "no TOC, using generic one" + log:info "no TOC, using a generic one" local inputfile = input .. "." .. ext - print("Main file name", inputfile) + log:info("Main file name: ".. inputfile) -- write toc file local toc_name = "generic_toc" .."."..ext local f = io.open(outputdir .. "/" .. toc_name, "w") @@ -142,6 +259,7 @@ local function cleanOPF() content = eb.remove_empty_guide(content) content = add_media_overlays(content) + content = fix_properties(content) f = io.open(outputdir .. "/" ..opf,"w") f:write(content) f:close() @@ -152,6 +270,7 @@ end function writeContainer() --local ret = eb.writeContainer() + log:info "write container" eb.make_opf() cleanOPF() local ret = eb.pack_container() diff --git a/Master/texmf-dist/scripts/tex4ebook/exec_mobi.lua b/Master/texmf-dist/scripts/tex4ebook/exec_mobi.lua index 11871ade769..ce10b6da760 100755 --- a/Master/texmf-dist/scripts/tex4ebook/exec_mobi.lua +++ b/Master/texmf-dist/scripts/tex4ebook/exec_mobi.lua @@ -1,6 +1,7 @@ module(...,package.seeall) local eb = require("exec_epub") local ebookutils = require("mkutils") +local log = logging.new "exec_mobi" function prepare(params) return eb.prepare(params) @@ -14,7 +15,7 @@ function writeContainer() local ret = eb.writeContainer() -- convert the epub file to mobi local epubpath = eb.basedir .. "/" .. eb.outputfile - print("Pack mobi "..os.execute("kindlegen " .. epubpath)) + log:info("Pack mobi "..os.execute("kindlegen " .. epubpath)) -- find the mobi filename local mobifile = epubpath:gsub("epub$", "mobi") local mobidist = eb.destdir .. eb.outputfile:gsub("epub$", "mobi") diff --git a/Master/texmf-dist/scripts/tex4ebook/tex4ebook b/Master/texmf-dist/scripts/tex4ebook/tex4ebook index a95bf44c236..731607fc5b4 100755 --- a/Master/texmf-dist/scripts/tex4ebook/tex4ebook +++ b/Master/texmf-dist/scripts/tex4ebook/tex4ebook @@ -5,6 +5,9 @@ kpse.set_program_name("luatex") require("lapp-mk4") -- require("ebookutils") +logging = require "make4ht-logging" +if os.type == "windows" then logging.use_colors = false end +local log = logging.new("tex4ebook") local ebookutils = require "mkutils" local mkparams = require "mkparams" local mk_config = require "make4ht-config" @@ -24,39 +27,37 @@ local output_formats={epub=true,mobi=true,epub3=true} local executor=nil local tidy = false local include_fonts = false + +-- message used for option parsing by the mkparams lib local arg_message = [[ tex4ebook - ebook generation support for LaTeX Usage: tex4ebook [switches] filename ["tex4ht.sty op."] ["tex4ht op."] ["t4ht op"] ["latex op"] + -a,--loglevel (default status) Set log level. + possible values: debug, info, status, warning, error, fatal -c,--config (default xhtml) Custom config file -d,--output-dir (default nil) Output directory -e,--build-file (default nil) If build file is different than `filename`.mk4 -f,--format (default epub) Output format. Supported values: epub, epub3, mobi -h,--help Display help message + -j,--jobname (default nil) Set the jobname -l,--lua Use lualatex for document compilation -m,--mode (default default) Switch which can be used in the makefile -r,--resolution (default 167) -s,--shell-escape Enable shell escape in htlatex run -t,--tidy Run html tidy on html output. May result in wrong spacing! - -v,--version Display version number -x,--xetex Use xelatex for document compilation + -v,--version Display version number + ]] - (string) Input file name - -Positional optional argumens: - ["tex4ht.sty op."] Additional parameters for tex4ht.sty - ["tex4ht op."] Options for tex4ht command - ["t4ht op"] Options for t4ht command - ["latex op"] Additional options for LaTeX +-- options for the template used by mkparams to generate the help message +local mkparams_parameters = { + progname = "tex4ebook", + issue_tracker = "https://github.com/michal-h21/tex4ebook/issues" +} -Documentation: https://tug.org/applications/tex4ht/mn.html -Issue tracker for tex4ht bugs: https://puszcza.gnu.org.ua/bugs/?group=tex4ht -Issue tracker for tex4ebook bugs: https://github.com/michal-h21/tex4ebook/issues -]] - --- This option is no longer available, all files must be unicode --- -u,--utf8 -local args=lapp(arg_message) +-- process the command line arguments +local args = mkparams.get_args(mkparams_parameters, arg_message) if args["filename"] == nil and args["version"] == false then print(arg_message) @@ -66,7 +67,7 @@ else end if args.version then - print "tex4ebook v0.2c" + print "tex4ebook v0.3" return end @@ -85,11 +86,6 @@ if args["include-fonts"] then include_fonts = true end --- local mathml = "," --- if args["mathml"] then --- -- mathml = ",mathml," --- tex4ht_sty_par = tex4ht_sty_par .. ",mathml" --- end local mode = args.mode or "default" if os.type=="unix" then @@ -109,25 +105,7 @@ if args.tidy then else tidy = false end --- Env file copying - ---[[if not ebookutils.file_exists("tex4ht.env") then -local env_file = kpse.find_file("epub2.env") -ebookutils.copy_filter(env_file,"tex4ht.env",function(s) return s % { -move = move_cmd, -copy = copy_cmd, -resolution = args.resolution -} end) -end--]] - ---print ("nazdar ${world}" % {world="svete"}) ---print(args.config) - -local input = ebookutils.remove_extension(input_file) -local config=ebookutils.remove_extension(args.config) --- local tex4ht_sty_par = config ..tex4ht_sty_par..","+args.format ---local sty_args = args[2] and ", " .. args[2] or "" local sty_args = "" if args[2] then sty_args = "," .. args[2] @@ -138,12 +116,17 @@ local t4ht_par = t4ht_par + args[4] local latex_par = latex_par + args[5] -- use default parameter processing from make4ht --- add some needed args +-- add some needed args (is it useful anymore?) args.filename=input_file + +-- let make4ht handle the common options local params = mkparams.process_args(args) +local input = params.input +log:status("Conversion started") +log:status("Input file: ".. params.tex_file) -local output_format = params.output_format --args.format +local output_format = params.output_format -- use epub as default output_format output_format = output_format or "epub" local extensions = ebookutils.load_extensions(params.extensions, output_format) @@ -152,7 +135,7 @@ local oldparams = { -- htlatex=latex_cmd -- ,input=input -- ,tex_file = tex_file - format= output_format + format = output_format -- ,latex_par=latex_par -- ,tex4ht_sty_par=tex4ht_sty_par -- ,tex4ht_par=tex4ht_par @@ -162,7 +145,6 @@ local oldparams = { ,tidy = tidy ,include_fonts = include_fonts ,resolution=args.resolution - ,mathml=mathml ,packages="\\RequirePackage{tex4ebook}" } @@ -175,25 +157,15 @@ params.tex4ht_sty_par=params.tex4ht_sty_par .. ",charset=utf-8,"..output_format params.tex4ht_par= " -cmozhtf -utf8" .. params.tex4ht_par -if output_formats[output_format] then - executor=require("exec_"..output_format) - params=executor.prepare(params) - if #extensions > 0 then - params = ebookutils.extensions_prepare_parameters(extensions,params) - end -else - print("Unknown output format: "..output_format) - return -end -- find tex4ebook configuration file local configname = "tex4ebook" local conffile = mk_config.find_config(configname) or mk_config.find_xdg_config(configname) if conffile then - print("Using configuration file: " .. conffile) + log:info("Using configuration file: " .. conffile) ebookutils.load_config(params, conffile) else - print "No conffile" + log:info "No conffile" end local build_file = input.. ".mk4" @@ -205,8 +177,20 @@ end local config_file = ebookutils.load_config(params, build_file) params["config_file"] = config_file + + +if output_formats[output_format] then + executor=require("exec_"..output_format) + params=executor.prepare(params) + if #extensions > 0 then + params = ebookutils.extensions_prepare_parameters(extensions,params) + end +else + log:error("Unknown output format: "..output_format) + return +end --config_file.Make:run() -print("${htlatex} ${input} \"${tex4ht_sty_par}\" \"${tex4ht_par}\" \"${t4ht_par}\" \"${latex_par}\"" % params) +-- print("${htlatex} ${input} \"${tex4ht_sty_par}\" \"${tex4ht_par}\" \"${t4ht_par}\" \"${latex_par}\"" % params) if #extensions > 0 then config_file.Make = ebookutils.extensions_modify_build(extensions, config_file.Make) end @@ -214,4 +198,5 @@ end executor.run(input,params) executor.writeContainer() executor.clean() +log:status("Conversion finished") --print(args[1]) -- cgit v1.2.3