texlive[52616] trunk: tex4ebook (2nov19)
commits+karl at tug.org
commits+karl at tug.org
Sat Nov 2 22:05:55 CET 2019
Revision: 52616
http://tug.org/svn/texlive?view=revision&revision=52616
Author: karl
Date: 2019-11-02 22:05:54 +0100 (Sat, 02 Nov 2019)
Log Message:
-----------
tex4ebook (2nov19)
Modified Paths:
--------------
trunk/Build/source/texk/texlive/linked_scripts/tex4ebook/tex4ebook
trunk/Master/texmf-dist/doc/support/tex4ebook/changelog.tex
trunk/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-doc.pdf
trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook
trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
trunk/Master/tlpkg/tlpsrc/dviout.win32.tlpsrc
trunk/Master/tlpkg/tlpsrc/pdfjam.tlpsrc
trunk/Master/tlpkg/tlpsrc/texworks.tlpsrc
Added Paths:
-----------
trunk/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-tidyconf.conf
trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua
trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub3.lua
trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_mobi.lua
Removed Paths:
-------------
trunk/Master/texmf-dist/doc/support/tex4ebook/tidyconf.conf
trunk/Master/texmf-dist/scripts/tex4ebook/config-t4e.lua
trunk/Master/texmf-dist/scripts/tex4ebook/exec_epub.lua
trunk/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua
trunk/Master/texmf-dist/scripts/tex4ebook/exec_mobi.lua
trunk/Master/texmf-dist/scripts/tex4ebook/list-fonts.lua
Modified: trunk/Build/source/texk/texlive/linked_scripts/tex4ebook/tex4ebook
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/tex4ebook/tex4ebook 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Build/source/texk/texlive/linked_scripts/tex4ebook/tex4ebook 2019-11-02 21:05:54 UTC (rev 52616)
@@ -67,7 +67,7 @@
end
if args.version then
- print "tex4ebook v0.3"
+ print "tex4ebook v0.3a"
return
end
@@ -180,7 +180,7 @@
if output_formats[output_format] then
- executor=require("exec_"..output_format)
+ executor=require("tex4ebook-exec_"..output_format)
params=executor.prepare(params)
if #extensions > 0 then
params = ebookutils.extensions_prepare_parameters(extensions,params)
Modified: trunk/Master/texmf-dist/doc/support/tex4ebook/changelog.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/tex4ebook/changelog.tex 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/texmf-dist/doc/support/tex4ebook/changelog.tex 2019-11-02 21:05:54 UTC (rev 52616)
@@ -8,6 +8,18 @@
\begin{itemize}
\tightlist
\item
+ released version \texttt{0.3a}
+ \item
+ added \texttt{tex4ebook-} prefix to the output formats.
+ \item
+ removed unused files.
+ \end{itemize}
+\item
+ 2019/11/01
+
+ \begin{itemize}
+ \tightlist
+ \item
released version \texttt{0.3}
\end{itemize}
\item
Modified: trunk/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-doc.pdf
===================================================================
(Binary files differ)
Added: trunk/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-tidyconf.conf
===================================================================
--- trunk/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-tidyconf.conf (rev 0)
+++ trunk/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-tidyconf.conf 2019-11-02 21:05:54 UTC (rev 52616)
@@ -0,0 +1,4 @@
+show-warnings: no
+numeric-entities:yes
+new-inline-tags:span,a,math,mi, mo, mn ,abs ,and ,annotation ,annotation-xml ,apply ,approx ,arccos ,arccosh ,arccot ,arccoth ,arccsc ,arccsch ,arcsec ,arcsech ,arcsin ,arcsinh ,arctan ,arctanh ,arg ,bind ,bvar ,card ,cartesianproduct ,cbytes ,ceiling ,cerror ,ci ,cn ,codomain ,complexes ,compose ,condition ,conjugate ,cos ,cosh ,cot ,coth ,cs ,csc ,csch ,csymbol ,curl ,declare ,degree ,determinant ,diff ,divergence ,divide ,domain ,domainofapplication ,el ,emptyset ,eq ,equivalent ,eulergamma ,exists ,exp ,exponentiale ,factorial ,factorof ,false ,floor ,fn ,forall ,gcd ,geq ,grad ,gt ,ident ,image ,imaginary ,imaginaryi ,implies ,in ,infinity ,int ,integers ,intersect ,interval ,inverse ,lambda ,laplacian ,lcm ,leq ,limit ,list ,ln ,log ,logbase ,lowlimit ,lt ,maction ,malign ,maligngroup ,malignmark ,malignscope ,math ,matrix ,matrixrow ,max ,mean ,median ,menclose ,merror ,mfenced ,mfrac ,mfraction ,mglyph ,mi ,min ,minus ,mlabeledtr ,mlongdiv ,mmultiscripts ,mn ,mo ,mode ,moment ,momentabout ,mover ,mpadded ,mphantom ,mprescripts ,mroot ,mrow ,ms ,mscarries ,mscarry ,msgroup ,msline ,mspace ,msqrt ,msrow ,mstack ,mstyle ,msub ,msubsup ,msup ,mtable ,mtd ,mtext ,mtr ,munder ,munderover ,naturalnumbers ,neq ,none ,not ,notanumber ,note ,notin ,notprsubset ,notsubset ,or ,otherwise ,outerproduct ,partialdiff ,pi ,piece ,piecewise ,plus ,power ,primes ,product ,prsubset ,quotient ,rationals ,real ,reals ,reln ,rem ,root ,scalarproduct ,sdev ,sec ,sech ,selector ,semantics ,sep ,set ,setdiff ,share ,sin ,sinh ,subset ,sum ,tan ,tanh ,tendsto ,times ,transpose ,true ,union ,uplimit ,variance ,vector ,vectorproduct ,xor ,bdi ,command ,details ,dialog ,summary ,figure ,figcaption ,footer ,header ,mark ,meter ,progress ,ruby ,rt ,rp ,time ,wbr ,altGlyph ,altGlyphDef ,altGlyphItem ,animate ,animateColor ,animateMotion ,animateTransform ,circle ,clipPath ,color-profile ,cursor ,defs ,desc ,ellipse ,feBlend ,feColorMatrix ,feComponentTransfer ,feComposite ,feConvolveMatrix ,feDiffuseLighting ,feDisplacementMap!
,feDistantLight ,feFlood ,feFuncA ,feFuncB ,feFuncG ,feFuncR ,feGaussianBlur ,feImage ,feMerge ,feMergeNode ,feMorphology ,feOffset ,fePointLight ,feSpecularLighting ,feSpotLight ,feTile ,feTurbulence ,filter ,font ,font-face ,font-face-format ,font-face-name ,font-face-src ,font-face-uri ,foreignObject ,g ,glyph ,glyphRef ,hkern ,image ,line ,linearGradient ,marker ,mask ,metadata ,missing-glyph ,mpath ,path ,pattern ,polygon ,polyline ,radialGradient ,rect ,script ,set ,stop ,style ,svg ,switch ,symbol ,text ,textPath ,title ,tref ,tspan ,use
+new-blocklevel-tags: aside,section,article,nav
Deleted: trunk/Master/texmf-dist/doc/support/tex4ebook/tidyconf.conf
===================================================================
--- trunk/Master/texmf-dist/doc/support/tex4ebook/tidyconf.conf 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/texmf-dist/doc/support/tex4ebook/tidyconf.conf 2019-11-02 21:05:54 UTC (rev 52616)
@@ -1,4 +0,0 @@
-show-warnings: no
-numeric-entities:yes
-new-inline-tags:span,a,math,mi, mo, mn ,abs ,and ,annotation ,annotation-xml ,apply ,approx ,arccos ,arccosh ,arccot ,arccoth ,arccsc ,arccsch ,arcsec ,arcsech ,arcsin ,arcsinh ,arctan ,arctanh ,arg ,bind ,bvar ,card ,cartesianproduct ,cbytes ,ceiling ,cerror ,ci ,cn ,codomain ,complexes ,compose ,condition ,conjugate ,cos ,cosh ,cot ,coth ,cs ,csc ,csch ,csymbol ,curl ,declare ,degree ,determinant ,diff ,divergence ,divide ,domain ,domainofapplication ,el ,emptyset ,eq ,equivalent ,eulergamma ,exists ,exp ,exponentiale ,factorial ,factorof ,false ,floor ,fn ,forall ,gcd ,geq ,grad ,gt ,ident ,image ,imaginary ,imaginaryi ,implies ,in ,infinity ,int ,integers ,intersect ,interval ,inverse ,lambda ,laplacian ,lcm ,leq ,limit ,list ,ln ,log ,logbase ,lowlimit ,lt ,maction ,malign ,maligngroup ,malignmark ,malignscope ,math ,matrix ,matrixrow ,max ,mean ,median ,menclose ,merror ,mfenced ,mfrac ,mfraction ,mglyph ,mi ,min ,minus ,mlabeledtr ,mlongdiv ,mmultiscripts ,mn ,mo ,mode ,moment ,momentabout ,mover ,mpadded ,mphantom ,mprescripts ,mroot ,mrow ,ms ,mscarries ,mscarry ,msgroup ,msline ,mspace ,msqrt ,msrow ,mstack ,mstyle ,msub ,msubsup ,msup ,mtable ,mtd ,mtext ,mtr ,munder ,munderover ,naturalnumbers ,neq ,none ,not ,notanumber ,note ,notin ,notprsubset ,notsubset ,or ,otherwise ,outerproduct ,partialdiff ,pi ,piece ,piecewise ,plus ,power ,primes ,product ,prsubset ,quotient ,rationals ,real ,reals ,reln ,rem ,root ,scalarproduct ,sdev ,sec ,sech ,selector ,semantics ,sep ,set ,setdiff ,share ,sin ,sinh ,subset ,sum ,tan ,tanh ,tendsto ,times ,transpose ,true ,union ,uplimit ,variance ,vector ,vectorproduct ,xor ,bdi ,command ,details ,dialog ,summary ,figure ,figcaption ,footer ,header ,mark ,meter ,progress ,ruby ,rt ,rp ,time ,wbr ,altGlyph ,altGlyphDef ,altGlyphItem ,animate ,animateColor ,animateMotion ,animateTransform ,circle ,clipPath ,color-profile ,cursor ,defs ,desc ,ellipse ,feBlend ,feColorMatrix ,feComponentTransfer ,feComposite ,feConvolveMatrix ,feDiffuseLighting ,feDisplacementMap!
,feDistantLight ,feFlood ,feFuncA ,feFuncB ,feFuncG ,feFuncR ,feGaussianBlur ,feImage ,feMerge ,feMergeNode ,feMorphology ,feOffset ,fePointLight ,feSpecularLighting ,feSpotLight ,feTile ,feTurbulence ,filter ,font ,font-face ,font-face-format ,font-face-name ,font-face-src ,font-face-uri ,foreignObject ,g ,glyph ,glyphRef ,hkern ,image ,line ,linearGradient ,marker ,mask ,metadata ,missing-glyph ,mpath ,path ,pattern ,polygon ,polyline ,radialGradient ,rect ,script ,set ,stop ,style ,svg ,switch ,symbol ,text ,textPath ,title ,tref ,tspan ,use
-new-blocklevel-tags: aside,section,article,nav
Deleted: trunk/Master/texmf-dist/scripts/tex4ebook/config-t4e.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/tex4ebook/config-t4e.lua 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/texmf-dist/scripts/tex4ebook/config-t4e.lua 2019-11-02 21:05:54 UTC (rev 52616)
@@ -1,19 +0,0 @@
--- Config file for tex4ebook
-
--- Font config
-
-Font{
- name = "cmr",
- file = "lmroman10-regular.otf",
- family = "Latin Modern",
- weight = "normal",
- style = "normal"
-}
-
-Font{
- name = "cmmi",
- file = "lmroman10-italic.otf",
- family = "Latin Modern",
- weight = "normal",
- style = "italic"
-}
Deleted: trunk/Master/texmf-dist/scripts/tex4ebook/exec_epub.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/tex4ebook/exec_epub.lua 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/texmf-dist/scripts/tex4ebook/exec_epub.lua 2019-11-02 21:05:54 UTC (rev 52616)
@@ -1,344 +0,0 @@
-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
--- and it is different between TL and Miktex
--- local load_font = require("list-fonts")
-local outputdir_name="OEBPS"
-local metadir_name = "META-INF"
-local mimetype_name="mimetype"
-outputdir=""
-outputfile=""
-outputfilename=""
--- the directory where the epub file should be moved to
-destdir=""
-basedir = ""
-tidy = false
-local include_fonts = false
-local metadir=""
-
--- from https://stackoverflow.com/a/43407750/2467963
-local function deletedir(dir)
- local attr = lfs.attributes(dir)
- if attr then
- for file in lfs.dir(dir) do
- local file_path = dir..'/'..file
- if file ~= "." and file ~= ".." then
- if lfs.attributes(file_path, 'mode') == 'file' then
- os.remove(file_path)
- log:info('remove file',file_path)
- elseif lfs.attributes(file_path, 'mode') == 'directory' then
- log:info('dir', file_path)
- deletedir(file_path)
- end
- end
- end
- lfs.rmdir(dir)
- end
- log:info('remove dir',dir)
-end
-
-function prepare(params)
- local makedir= function(path)
- local current = lfs.currentdir()
- local dir = ebookutils.prepare_path(path .. "/")
- if type(dir) == "table" then
- local parts,msg = ebookutils.find_directories(dir)
- if parts then
- ebookutils.mkdirectories(parts)
- end
- end
- lfs.chdir(current)
- end
- basedir = params.input.."-".. params.format
- outputdir= basedir.."/"..outputdir_name
- deletedir(basedir)
- makedir(outputdir)
- metadir = basedir .."/" .. metadir_name
- makedir(metadir)
- if params.outdir ~= "" then
- destdir = params.outdir .. "/"
- makedir(destdir)
- end
- mimetype= basedir .. "/" ..mimetype_name --os.tmpname()
- 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
-
-function run(out,params)
- --local currentdir=
- outputfilename=out
- outputfile = outputfilename..".epub"
- log:info("Output file: "..outputfile)
- --lfs.chdir(metadir)
- local m= io.open(metadir.."/container.xml","w")
- m:write([[
-<?xml version="1.0"?>
-<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
-<rootfiles>
-<rootfile full-path="OEBPS/content.opf"
-media-type="application/oebps-package+xml"/>
-</rootfiles>
-</container>
- ]])
- m:close()
- --lfs.chdir("..")
- m=io.open(mimetype,"w")
- m:write("application/epub+zip")
- m:close()
- params.config_file.Make:run()
- --[[for k,v in pairs(params.config_file.Make) do
- print(k.. " : "..type(v))
- end--]]
- --print(os.execute(htlatex_run))
-end
-
-local mimetypes = {
- css = "text/css",
- png = "image/png",
- jpg = "image/jpeg",
- gif = "image/gif",
- svg = "image/svg+xml",
- html= "application/xhtml+xml",
- xhtml= "application/xhtml+xml",
- ncx = "application/x-dtbncx+xml",
- otf = "application/opentype",
- ttf = "application/truetype",
- woff = "application/font-woff",
- js = "text/javascript",
- mp3 = "audio/mpeg",
- smil = "application/smil+xml"
-}
-
-function remove_empty_guide(content)
- return content:gsub("<guide>%s*</guide>","")
-end
-
-function make_opf()
- -- Join files content.opf and content-part2.opf
- -- make item record for every converted image
- local lg_item = function(item)
- -- 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 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
- -- remove invalid characters from id start
- id = id:gsub("^[%.%-]*","")
- return "<item id='"..id .. "' href='"..item.."' media-type='"..mimetype.."' />",id
- end
- local find_all_files= function(s,r)
- local r = r or "([%a%d%_%-]*)%.([x]?html)"
- local files = {}
- for i, ext in s:gmatch(r) do
- --local i, ext = s:match(r)-- do
- ext = ext or "true"
- files[i] = ext
- end
- return files
- end
- local tidyconf = nil
- if tidy then
- tidyconf = kpse.find_file("tidyconf.conf")
- end
- --local opf_first_part = outputdir .. "/content.opf"
- local opf_first_part = "content.opf"
- local opf_second_part = "content-part2.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
- 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
- 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
- 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,
- '<itemref idref="${idref}" linear="no" />' % {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
- 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
- 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
- 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 clean()
- --deldir(outputdir)
- --deldir(metadir)
- --os.remove(mimetype)
-end
Deleted: trunk/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua 2019-11-02 21:05:54 UTC (rev 52616)
@@ -1,282 +0,0 @@
-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
-local input = nil
-function prepare(params)
- local basedir = params.input.."-".. params.format
- local outputdir_name="OEBPS"
- outputdir= basedir.."/"..outputdir_name
- input = params.input
- params.ext = ext
- params.tex4ht_sty_par = params.tex4ht_sty_par .. ",html5"
- params.packages = params.packages .. string.format("\\Configure{ext}{%s}",ext)
- return eb.prepare(params)
-end
-
-function run(out,params)
- return eb.run(out, params)
-end
-
-
-local function makeTOC(document)
- local template = [[
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:epub="http://www.idpf.org/2007/ops"
->
-<head><title>TOC</title></head>
-<body>
-<nav id="pub-toc" epub:type="toc">
- <h1>Table of contents</h1>
- <ol class="toc" hidden="hidden">
- <li>
- <a href="${document}">Document</a>
- </li>
- </ol>
-</nav>
-</body>
-</html>
-]] % {document=document}
- return template
-end
-
-local function add_media_overlays(content)
- local add_meta = function(package, attributes, text)
- local meta = package:create_element("meta",attributes)
- local dur_el = meta:create_text_node(text)
- meta:add_child_node(dur_el)
- package:add_child_node(meta)
- end
- -- calculate total audio time
- local calc_times = function(times)
- local time = 0
- for _, curr in ipairs(times) do
- -- smil file contains timestamps in the H:M:S format, we need to parse it
- local hours, minutes, seconds = curr:match("(%d+):(%d+):(%d+)")
- time = time + os.time({year=1970, day=1, month=1, hour=hours, min=minutes, sec=seconds})
- end
- return os.date("%H:%M:%S",time)
- end
- -- 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
- -- <meta> 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 = {}
- local package = opfdom:query_selector("metadata")[1]
- -- we must read all smil files and find references to html files
- -- it is necessary to add media-overlay attribute to the referenced items
- for _, item in ipairs(items) do
- local href = item:get_attribute("href")
- ref[href] = item
- -- we must read audio length from the smil file and add it as a <meta> property
- if href:match("smil$") then
- local f = io.open(outputdir .. "/" .. href, "r")
- if not f then break end
- local smil = f:read("*all")
- f:close()
- local smildom = dom.parse(smil)
- local audios = smildom:query_selector("audio")
- local last = audios[#audios]
- -- add audio duration to the metadata section
- if last then
- local duration = last:get_attribute("clipend")
- if duration then
- -- todo: calculate total audio length
- table.insert(times, duration)
- local audio_id = item:get_attribute("id")
- add_meta(package, {property="media:duration", refines="#"..audio_id}, duration)
- end
- end
-
- -- add the media-overlay attribute
- local textref = smil:match('epub:textref="(.-)"')
- local id = item:get_attribute("id")
- local referenced = ref[textref]
- if referenced then
- referenced:set_attribute("media-overlay", id)
- end
- end
- end
- -- calculate length of all media overlay audio files
- if #times > 0 then
- local totaltime = calc_times(times)
- add_meta(package,{property="media:duration"}, totaltime)
- end
- local serialized = opfdom:serialize()
- return serialized
-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 <li> to empty <ol>
- 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 <li> elements to an <a> element, epubcheck reports
- -- error for text nodes that are direct child of <li>
- for _, el in ipairs(tocdom:query_selector("li")) do
- local text = {}
- local link -- save the <a> 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 <spine> element, so we need to move them
- -- here from the <manifest> 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
- 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
- log:info "TOC nav found"
- cleanTOC(content)
- else
- log:info "no TOC, using a generic one"
- local inputfile = input .. "." .. ext
- log:info("Main file name: ".. inputfile)
- -- write toc file
- local toc_name = "generic_toc" .."."..ext
- local f = io.open(outputdir .. "/" .. toc_name, "w")
- f:write(makeTOC(inputfile))
- f:close()
- -- add toc file to the conten.opf
- content = content:gsub("<manifest>","<manifest>\n<item id='htmltoc'" ..
- " properties=\"nav\" media-type=\"application/xhtml+xml\" href=\""..
- toc_name .."\" />\n")
- content = content:gsub("<spine([^>]*)>", "<spine%1>\n<itemref idref=\"htmltoc\" linear=\"no\"/>\n")
- -- remove empty guide element
- end
- -- content = content:gsub("<guide>%s*</guide>","")
- 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()
- --makeTOC(inputfile)
-end
-
-
-
-function writeContainer()
- --local ret = eb.writeContainer()
- log:info "write container"
- eb.make_opf()
- cleanOPF()
- local ret = eb.pack_container()
- return ret
-end
-
-function clean()
- return eb.clean()
-end
Deleted: trunk/Master/texmf-dist/scripts/tex4ebook/exec_mobi.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/tex4ebook/exec_mobi.lua 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/texmf-dist/scripts/tex4ebook/exec_mobi.lua 2019-11-02 21:05:54 UTC (rev 52616)
@@ -1,32 +0,0 @@
-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)
-end
-
-function run(out,params)
- return eb.run(out, params)
-end
-
-function writeContainer()
- local ret = eb.writeContainer()
- -- convert the epub file to mobi
- local epubpath = eb.basedir .. "/" .. eb.outputfile
- 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")
- -- copy the mobi file to the destination directory
- -- the destination directory will be created by the epub writer, so it is possible to use
- -- the cp function which doesn't try to create directory
- ebookutils.cp(mobifile, mobidist)
-
- return ret
-end
-
-function clean()
- return eb.clean()
-end
Deleted: trunk/Master/texmf-dist/scripts/tex4ebook/list-fonts.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/tex4ebook/list-fonts.lua 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/texmf-dist/scripts/tex4ebook/list-fonts.lua 2019-11-02 21:05:54 UTC (rev 52616)
@@ -1,145 +0,0 @@
-kpse.set_program_name("luatex")
-local function exists(fn)
- local f = io.open(fn,"r")
- if f~=nil then io.close(f) return true else return false end
-end
-local function load_fontbase(pathtable)
- -- path should point to possible location of luaotfload font database
- -- pathtable should be array of strings
- -- each path should not end with lua
-
- local path = pathtable
- if type(pathtable) =="string" then path = {pathtable} end
- if #path == 0 then return nil end
- local currentpath = table.remove(path,1)
- if exists(currentpath ..".lua") then return require(currentpath)
- else return load_fontbase(path) end
-end
-
---local fontbase = require(kpse.expand_var("$TEXMFSYSVAR") .. "/luatex-cache/generic/names/luaotfload-names.lua")
-local sysvar = kpse.expand_var("$TEXMFSYSVAR")
-local var = kpse.expand_var("$TEXMFVAR")
-local namespath = "/luatex-cache/generic/names/"
-local oldnames = "otfl-names"
-local newnames = "luaotfload-names"
-local compose_path = function(path, name) return path .. namespath .. name end
-local fontbase_path = {
- compose_path(sysvar, newnames),
- compose_path(var, newnames),
- compose_path(sysvar, oldnames),
- compose_path(var,oldnames)
-}
-
-local fontbase = load_fontbase(fontbase_path) or {}
-fontbase.mappings = fontbase.mappings or {}
--- assert(fontbase, "Cannot load font names")
-
-
--- [[
--- This is code for querying the database
---
-local search = arg[1] or ""
-search = unicode.utf8.lower(search)
---]]
-local fonts = {}
-for _,record in pairs(fontbase.mappings) do
- local familyname = record.familyname
- local styles = fonts[familyname] or {}
- local sanitized = record.sanitized or record.names
- local subfamily = sanitized.subfamily --record.sanitized.subfamily or record.names.subfamily
- styles[subfamily] = record -- We add subfamily as key to prevent duplicates
- fonts[familyname] = styles
-end
-
-local FontLoader = {}
-
-FontLoader.__index = FontLoader
-
-FontLoader.load_family = function(familyname)
- local self = setmetatable({},FontLoader)
- local family = fonts[familyname]
- --[[ for _, record in pairs(fontbase.mappings) do
- if record.familyname == familyname then
- local style = record.sanitized.subfamily
- family[style] = record
- end
- end
- --]]
- self.family = family
- return self
-end
-FontLoader.get_path =function(self,style)
- local rec = self.family[style]
- local filename = rec.filename
- if type(filename) == "table" then
- filename = filename[1]
- end
- return kpse.find_file(filename,'opentype fonts') or kpse.find_file(filename,'truetype fonts')
-end
-
-
-FontLoader.list = function(self)
- for style,rec in pairs(self.family) do
- print(style, self:get_path(style))
- end
-end
-
-
-local FontNames = {}
-FontNames.__index = FontNames
-
-FontNames.new = function()
- self = setmetatable({},FontNames)
- self.names = {}
- return self
-end
-
-FontNames.add_family = function(self,properties)
- local properties = properties or {}
- return function(names)
- local names = names or {}
- for _,n in pairs(names) do
- self.names[n] = properties
- end
- end
-end
-
-FontNames.list = function(self)
- for name,prop in pairs(self.names) do
- local p = {}
- for k,v in pairs(prop) do
- table.insert(p,k..'='..v)
- end
- print(name, table.concat(p))
- end
-end
-
---[[
-local fontnames = {}
-for fontname,_ in pairs(fonts) do
- local lowername = unicode.utf8.lower(fontname)
- if lowername:find(search) then
- table.insert(fontnames, fontname)
- end
-end
-
-table.sort(fontnames)
---for fontname, styles in pairs (fonts) do
-for _, name in pairs(fontnames) do
- local fontname = name
- local styles = fonts[fontname]
- local t = {}
- for n,_ in pairs(styles) do table.insert(t,n) end
- print(fontname, table.concat(t,', '))
-end
---]]
-
-local testfont = FontLoader.load_family("math")
---testfont:list()
-
-local n= FontNames.new()
-n:add_family {type = "serif", name = "LMMono10"} {"cmr"}
-n:add_family {type = "serif", name = "TeXGyreTermes"} {"ts1-qtmr", "ec-qtmr","ec-qtmri"}
---n:list()
-
-return {FontLoader = FontLoader, FontNames = n}
Modified: trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook
===================================================================
--- trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook 2019-11-02 21:05:54 UTC (rev 52616)
@@ -67,7 +67,7 @@
end
if args.version then
- print "tex4ebook v0.3"
+ print "tex4ebook v0.3a"
return
end
@@ -180,7 +180,7 @@
if output_formats[output_format] then
- executor=require("exec_"..output_format)
+ executor=require("tex4ebook-exec_"..output_format)
params=executor.prepare(params)
if #extensions > 0 then
params = ebookutils.extensions_prepare_parameters(extensions,params)
Added: trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua (rev 0)
+++ trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua 2019-11-02 21:05:54 UTC (rev 52616)
@@ -0,0 +1,341 @@
+module(...,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"
+local outputdir_name="OEBPS"
+local metadir_name = "META-INF"
+local mimetype_name="mimetype"
+outputdir=""
+outputfile=""
+outputfilename=""
+-- the directory where the epub file should be moved to
+destdir=""
+basedir = ""
+tidy = false
+local include_fonts = false
+local metadir=""
+
+-- from https://stackoverflow.com/a/43407750/2467963
+local function deletedir(dir)
+ local attr = lfs.attributes(dir)
+ if attr then
+ for file in lfs.dir(dir) do
+ local file_path = dir..'/'..file
+ if file ~= "." and file ~= ".." then
+ if lfs.attributes(file_path, 'mode') == 'file' then
+ os.remove(file_path)
+ log:info('remove file',file_path)
+ elseif lfs.attributes(file_path, 'mode') == 'directory' then
+ log:info('dir', file_path)
+ deletedir(file_path)
+ end
+ end
+ end
+ lfs.rmdir(dir)
+ end
+ log:info('remove dir',dir)
+end
+
+function prepare(params)
+ local makedir= function(path)
+ local current = lfs.currentdir()
+ local dir = ebookutils.prepare_path(path .. "/")
+ if type(dir) == "table" then
+ local parts,msg = ebookutils.find_directories(dir)
+ if parts then
+ ebookutils.mkdirectories(parts)
+ end
+ end
+ lfs.chdir(current)
+ end
+ basedir = params.input.."-".. params.format
+ outputdir= basedir.."/"..outputdir_name
+ deletedir(basedir)
+ makedir(outputdir)
+ metadir = basedir .."/" .. metadir_name
+ makedir(metadir)
+ if params.outdir ~= "" then
+ destdir = params.outdir .. "/"
+ makedir(destdir)
+ end
+ mimetype= basedir .. "/" ..mimetype_name --os.tmpname()
+ 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
+
+function run(out,params)
+ --local currentdir=
+ outputfilename=out
+ outputfile = outputfilename..".epub"
+ log:info("Output file: "..outputfile)
+ --lfs.chdir(metadir)
+ local m= io.open(metadir.."/container.xml","w")
+ m:write([[
+<?xml version="1.0"?>
+<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
+<rootfiles>
+<rootfile full-path="OEBPS/content.opf"
+media-type="application/oebps-package+xml"/>
+</rootfiles>
+</container>
+ ]])
+ m:close()
+ --lfs.chdir("..")
+ m=io.open(mimetype,"w")
+ m:write("application/epub+zip")
+ m:close()
+ params.config_file.Make:run()
+ --[[for k,v in pairs(params.config_file.Make) do
+ print(k.. " : "..type(v))
+ end--]]
+ --print(os.execute(htlatex_run))
+end
+
+local mimetypes = {
+ css = "text/css",
+ png = "image/png",
+ jpg = "image/jpeg",
+ gif = "image/gif",
+ svg = "image/svg+xml",
+ html= "application/xhtml+xml",
+ xhtml= "application/xhtml+xml",
+ ncx = "application/x-dtbncx+xml",
+ otf = "application/opentype",
+ ttf = "application/truetype",
+ woff = "application/font-woff",
+ js = "text/javascript",
+ mp3 = "audio/mpeg",
+ smil = "application/smil+xml"
+}
+
+function remove_empty_guide(content)
+ return content:gsub("<guide>%s*</guide>","")
+end
+
+function make_opf()
+ -- Join files content.opf and content-part2.opf
+ -- make item record for every converted image
+ local lg_item = function(item)
+ -- 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 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
+ -- remove invalid characters from id start
+ id = id:gsub("^[%.%-]*","")
+ return "<item id='"..id .. "' href='"..item.."' media-type='"..mimetype.."' />",id
+ end
+ local find_all_files= function(s,r)
+ local r = r or "([%a%d%_%-]*)%.([x]?html)"
+ local files = {}
+ for i, ext in s:gmatch(r) do
+ --local i, ext = s:match(r)-- do
+ ext = ext or "true"
+ files[i] = ext
+ end
+ return files
+ end
+ local tidyconf = nil
+ if tidy then
+ tidyconf = kpse.find_file("tex4ebook-tidyconf.conf")
+ end
+ --local opf_first_part = outputdir .. "/content.opf"
+ local opf_first_part = "content.opf"
+ local opf_second_part = "content-part2.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
+ 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
+ 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
+ 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,
+ '<itemref idref="${idref}" linear="no" />' % {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
+ 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
+ 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
+ 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 clean()
+ --deldir(outputdir)
+ --deldir(metadir)
+ --os.remove(mimetype)
+end
Property changes on: trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub3.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub3.lua (rev 0)
+++ trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub3.lua 2019-11-02 21:05:54 UTC (rev 52616)
@@ -0,0 +1,282 @@
+module(...,package.seeall)
+local eb = require("tex4ebook-exec_epub")
+local dom = require("luaxml-domobject")
+local log = logging.new "exec_epub3"
+
+local ext = "xhtml"
+local outputdir = nil
+local input = nil
+function prepare(params)
+ local basedir = params.input.."-".. params.format
+ local outputdir_name="OEBPS"
+ outputdir= basedir.."/"..outputdir_name
+ input = params.input
+ params.ext = ext
+ params.tex4ht_sty_par = params.tex4ht_sty_par .. ",html5"
+ params.packages = params.packages .. string.format("\\Configure{ext}{%s}",ext)
+ return eb.prepare(params)
+end
+
+function run(out,params)
+ return eb.run(out, params)
+end
+
+
+local function makeTOC(document)
+ local template = [[
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:epub="http://www.idpf.org/2007/ops"
+>
+<head><title>TOC</title></head>
+<body>
+<nav id="pub-toc" epub:type="toc">
+ <h1>Table of contents</h1>
+ <ol class="toc" hidden="hidden">
+ <li>
+ <a href="${document}">Document</a>
+ </li>
+ </ol>
+</nav>
+</body>
+</html>
+]] % {document=document}
+ return template
+end
+
+local function add_media_overlays(content)
+ local add_meta = function(package, attributes, text)
+ local meta = package:create_element("meta",attributes)
+ local dur_el = meta:create_text_node(text)
+ meta:add_child_node(dur_el)
+ package:add_child_node(meta)
+ end
+ -- calculate total audio time
+ local calc_times = function(times)
+ local time = 0
+ for _, curr in ipairs(times) do
+ -- smil file contains timestamps in the H:M:S format, we need to parse it
+ local hours, minutes, seconds = curr:match("(%d+):(%d+):(%d+)")
+ time = time + os.time({year=1970, day=1, month=1, hour=hours, min=minutes, sec=seconds})
+ end
+ return os.date("%H:%M:%S",time)
+ end
+ -- 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
+ -- <meta> 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 = {}
+ local package = opfdom:query_selector("metadata")[1]
+ -- we must read all smil files and find references to html files
+ -- it is necessary to add media-overlay attribute to the referenced items
+ for _, item in ipairs(items) do
+ local href = item:get_attribute("href")
+ ref[href] = item
+ -- we must read audio length from the smil file and add it as a <meta> property
+ if href:match("smil$") then
+ local f = io.open(outputdir .. "/" .. href, "r")
+ if not f then break end
+ local smil = f:read("*all")
+ f:close()
+ local smildom = dom.parse(smil)
+ local audios = smildom:query_selector("audio")
+ local last = audios[#audios]
+ -- add audio duration to the metadata section
+ if last then
+ local duration = last:get_attribute("clipend")
+ if duration then
+ -- todo: calculate total audio length
+ table.insert(times, duration)
+ local audio_id = item:get_attribute("id")
+ add_meta(package, {property="media:duration", refines="#"..audio_id}, duration)
+ end
+ end
+
+ -- add the media-overlay attribute
+ local textref = smil:match('epub:textref="(.-)"')
+ local id = item:get_attribute("id")
+ local referenced = ref[textref]
+ if referenced then
+ referenced:set_attribute("media-overlay", id)
+ end
+ end
+ end
+ -- calculate length of all media overlay audio files
+ if #times > 0 then
+ local totaltime = calc_times(times)
+ add_meta(package,{property="media:duration"}, totaltime)
+ end
+ local serialized = opfdom:serialize()
+ return serialized
+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 <li> to empty <ol>
+ 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 <li> elements to an <a> element, epubcheck reports
+ -- error for text nodes that are direct child of <li>
+ for _, el in ipairs(tocdom:query_selector("li")) do
+ local text = {}
+ local link -- save the <a> 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 <spine> element, so we need to move them
+ -- here from the <manifest> 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
+ 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
+ log:info "TOC nav found"
+ cleanTOC(content)
+ else
+ log:info "no TOC, using a generic one"
+ local inputfile = input .. "." .. ext
+ log:info("Main file name: ".. inputfile)
+ -- write toc file
+ local toc_name = "generic_toc" .."."..ext
+ local f = io.open(outputdir .. "/" .. toc_name, "w")
+ f:write(makeTOC(inputfile))
+ f:close()
+ -- add toc file to the conten.opf
+ content = content:gsub("<manifest>","<manifest>\n<item id='htmltoc'" ..
+ " properties=\"nav\" media-type=\"application/xhtml+xml\" href=\""..
+ toc_name .."\" />\n")
+ content = content:gsub("<spine([^>]*)>", "<spine%1>\n<itemref idref=\"htmltoc\" linear=\"no\"/>\n")
+ -- remove empty guide element
+ end
+ -- content = content:gsub("<guide>%s*</guide>","")
+ 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()
+ --makeTOC(inputfile)
+end
+
+
+
+function writeContainer()
+ --local ret = eb.writeContainer()
+ log:info "write container"
+ eb.make_opf()
+ cleanOPF()
+ local ret = eb.pack_container()
+ return ret
+end
+
+function clean()
+ return eb.clean()
+end
Property changes on: trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub3.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_mobi.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_mobi.lua (rev 0)
+++ trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_mobi.lua 2019-11-02 21:05:54 UTC (rev 52616)
@@ -0,0 +1,32 @@
+module(...,package.seeall)
+local eb = require("tex4ebook-exec_epub")
+local ebookutils = require("mkutils")
+local log = logging.new "exec_mobi"
+
+function prepare(params)
+ return eb.prepare(params)
+end
+
+function run(out,params)
+ return eb.run(out, params)
+end
+
+function writeContainer()
+ local ret = eb.writeContainer()
+ -- convert the epub file to mobi
+ local epubpath = eb.basedir .. "/" .. eb.outputfile
+ 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")
+ -- copy the mobi file to the destination directory
+ -- the destination directory will be created by the epub writer, so it is possible to use
+ -- the cp function which doesn't try to create directory
+ ebookutils.cp(mobifile, mobidist)
+
+ return ret
+end
+
+function clean()
+ return eb.clean()
+end
Property changes on: trunk/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_mobi.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc 2019-11-02 21:05:54 UTC (rev 52616)
@@ -526,7 +526,7 @@
depend glossaries-portuges
depend glossaries-serbian
depend glossaries-slovene
-depend glossaries-spanish
+depend glossaries-spanish
depend gmdoc
depend gmdoc-enhance
depend gmiflink
Modified: trunk/Master/tlpkg/tlpsrc/dviout.win32.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/dviout.win32.tlpsrc 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/tlpkg/tlpsrc/dviout.win32.tlpsrc 2019-11-02 21:05:54 UTC (rev 52616)
@@ -2,7 +2,7 @@
binpattern d/win32 tlpkg/dviout
binpattern f/win32 bin/win32/dviout
postaction shortcut type=menu name="DVIOUT DVI viewer" \
- cmd=TEXDIR/bin/win32/dviout.exe
+ cmd=TEXDIR/bin/win32/dviout.exe
postaction filetype name=TL.DVIOUT.view \
cmd='"TEXDIR/bin/win32/dviout.exe" "%1"'
postaction fileassoc extension=.dvi filetype=TL.DVIOUT.view
Modified: trunk/Master/tlpkg/tlpsrc/pdfjam.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/pdfjam.tlpsrc 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/tlpkg/tlpsrc/pdfjam.tlpsrc 2019-11-02 21:05:54 UTC (rev 52616)
@@ -9,7 +9,7 @@
binpattern f bin/${ARCH}/pdfjam
binpattern f bin/${ARCH}/pdfjoin
binpattern f bin/${ARCH}/pdfnup
-binpattern f bin/${ARCH}/pdfpun
+binpattern f bin/${ARCH}/pdfpun
#
runpattern f texmf-dist/scripts/pdfjam/pdf180
runpattern f texmf-dist/scripts/pdfjam/pdf270
@@ -22,7 +22,7 @@
runpattern f texmf-dist/scripts/pdfjam/pdfjam
runpattern f texmf-dist/scripts/pdfjam/pdfjoin
runpattern f texmf-dist/scripts/pdfjam/pdfnup
-runpattern f texmf-dist/scripts/pdfjam/pdfpun
+runpattern f texmf-dist/scripts/pdfjam/pdfpun
#
docpattern +f texmf-dist/doc/man/man1/pdf180.*
docpattern +f texmf-dist/doc/man/man1/pdf270.*
@@ -35,4 +35,4 @@
docpattern +f texmf-dist/doc/man/man1/pdfjam.*
docpattern +f texmf-dist/doc/man/man1/pdfjoin.*
docpattern +f texmf-dist/doc/man/man1/pdfnup.*
-docpattern +f texmf-dist/doc/man/man1/pdfpun.*
+docpattern +f texmf-dist/doc/man/man1/pdfpun.*
Modified: trunk/Master/tlpkg/tlpsrc/texworks.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/texworks.tlpsrc 2019-11-02 16:13:30 UTC (rev 52615)
+++ trunk/Master/tlpkg/tlpsrc/texworks.tlpsrc 2019-11-02 21:05:54 UTC (rev 52616)
@@ -4,7 +4,7 @@
longdesc TeX Live includes executables and support files only for Windows.
postaction shortcut type=menu name="TeXworks editor" \
- cmd=TEXDIR/bin/win32/texworks.exe
+ cmd=TEXDIR/bin/win32/texworks.exe
postaction filetype name=TL.TeXworks.edit \
cmd='"TEXDIR/bin/win32/texworks.exe" "%1"'
postaction fileassoc extension=.tex filetype=TL.TeXworks.edit
More information about the tex-live-commits
mailing list