summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-09-07 21:24:02 +0000
committerKarl Berry <karl@freefriends.org>2020-09-07 21:24:02 +0000
commitc332fb0ced3affd7fa1d93fed75108915db3cb7f (patch)
treea4fd48e0fb1c720f7e57f6c344a0ee65386036b6 /Master/texmf-dist/scripts
parenta4f2e39309134e43404848efae785e7b37319393 (diff)
tex4ebook (7sep20)
git-svn-id: svn://tug.org/texlive/trunk@56290 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts')
-rwxr-xr-xMaster/texmf-dist/scripts/tex4ebook/tex4ebook8
-rwxr-xr-xMaster/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw.lua35
-rwxr-xr-xMaster/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw3.lua35
-rwxr-xr-xMaster/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua113
4 files changed, 188 insertions, 3 deletions
diff --git a/Master/texmf-dist/scripts/tex4ebook/tex4ebook b/Master/texmf-dist/scripts/tex4ebook/tex4ebook
index ebd7485c2d1..dc602c4e72b 100755
--- a/Master/texmf-dist/scripts/tex4ebook/tex4ebook
+++ b/Master/texmf-dist/scripts/tex4ebook/tex4ebook
@@ -23,7 +23,7 @@ local tex4ht_sty_par=""
local tex4ht_par=""
local t4ht_par=""
local latex_par=""
-local output_formats={epub=true,mobi=true,epub3=true}
+local output_formats={epub=true,mobi=true,epub3=true,azw=true, azw3=true}
local executor=nil
local tidy = false
local include_fonts = false
@@ -67,7 +67,7 @@ else
end
if args.version then
- print "tex4ebook v0.3a"
+ print "tex4ebook v0.3b"
return
end
@@ -129,7 +129,9 @@ log:status("Input file: ".. params.tex_file)
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)
+-- load common_domfilters extension by default
+local extensions = ebookutils.add_extensions("+common_domfilters", params.extensions)
+extensions = ebookutils.load_extensions(extensions, output_format)
-- but also support tex4ebook!s own parameters
local oldparams = {
-- htlatex=latex_cmd
diff --git a/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw.lua b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw.lua
new file mode 100755
index 00000000000..397292b648b
--- /dev/null
+++ b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw.lua
@@ -0,0 +1,35 @@
+module(...,package.seeall)
+local eb = require("tex4ebook-exec_epub")
+local ebookutils = require("mkutils")
+local log = logging.new "exec_azw"
+
+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 azw
+ local epubpath = eb.basedir .. "/" .. eb.outputfile
+
+ -- find the azw filename
+ local azwfile = eb.outputfile:gsub("epub$", "azw")
+ local azwdist = eb.destdir .. azwfile
+ local command = "kindlegen " .. epubpath .. " -o " .. azwfile
+ log:info("Pack azw ".. command)
+ local status, output = ebookutils.execute(command)
+ -- copy the azw 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(eb.basedir .. "/" .. azwfile, azwdist)
+
+ return ret
+end
+
+function clean()
+ return eb.clean()
+end
diff --git a/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw3.lua b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw3.lua
new file mode 100755
index 00000000000..33e8a1182c5
--- /dev/null
+++ b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw3.lua
@@ -0,0 +1,35 @@
+module(...,package.seeall)
+local eb = require("tex4ebook-exec_epub")
+local ebookutils = require("mkutils")
+local log = logging.new "exec_azw"
+
+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 azw
+ local epubpath = eb.basedir .. "/" .. eb.outputfile
+
+ -- find the azw filename
+ local azwfile = eb.outputfile:gsub("epub$", "azw3")
+ local azwdist = eb.destdir .. azwfile
+ local command = "kindlegen " .. epubpath .. " -o " .. azwfile
+ log:info("Pack azw ".. command)
+ local status, output = ebookutils.execute(command)
+ -- copy the azw 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(eb.basedir .. "/" .. azwfile, azwdist)
+
+ return ret
+end
+
+function clean()
+ return eb.clean()
+end
diff --git a/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua
index 52e2ab6134d..b0ccee62027 100755
--- a/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua
+++ b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua
@@ -5,6 +5,7 @@ local io = require("io")
local log = logging.new("exec_epub")
--local ebookutils = require("ebookutils")
local ebookutils = require "mkutils"
+local dom = require("luaxml-domobject")
local outputdir_name="OEBPS"
local metadir_name = "META-INF"
local mimetype_name="mimetype"
@@ -319,11 +320,123 @@ function pack_container()
ebookutils.cp(basedir .."/"..outputfile, destdir .. outputfile)
end
+local function update_file(filename, fn)
+ -- update contents of a filename using function
+ local f = io.open(filename, "r")
+ local content = f:read("*all")
+ f:close()
+ local newcontent = fn(content)
+ local f = io.open(filename, "w")
+ f:write(newcontent)
+ f:close()
+end
+
+local function fix_ncx_toc_levels(dom)
+ -- OK, this is a weird hack. The problem is that when \backmatter
+ -- follows \part, the subsequent chapters are listed under part
+ -- in the NCX TOC
+ -- I've added special element <navmark> to the ncx file to detect mark numbers.
+ -- chapters in backmatter should have empty mark number
+
+ -- get current <navpoint> section type and mark number
+ local get_navpoint_info = function(navpoint)
+ local navmarks = navpoint:query_selector("navmark")
+ if navmarks and #navmarks > 0 then
+ -- we are interested only in the first navmark, because it contains the current navPoint info
+ local navmark = navmarks[1]
+ return navmark:get_attribute("type"), navmark:get_text()
+ end
+ return nil, "Cannot find navLabel"
+ end
+
+ local fix_chapters = function(part)
+ -- move chapters from backmatter and appendix from the current part
+ -- find part position in the element list, it will be place where backmatter will be moved
+ local part_pos = part:find_element_pos() + 1
+ local part_parent = part:get_parent()
+ -- child chapters
+ local children = part:get_children()
+ -- loop over children from back, where backmatter or appendix may be placed
+ for i = #children, 1, -1 do
+ local current = children[i]
+ local sect_type, mark = get_navpoint_info(current)
+ if sect_type then
+ -- remove spaces from mark
+ mark = mark:gsub("%s", "")
+ if sect_type == "appendix" or (sect_type == "chapter" and mark=="") then
+ -- move chapter at the same level as part, after part
+ -- the correct order will be kept, because we move from the back of the node list
+ -- and every new node is placed before previous added nodes
+ part_parent:add_child_node(current:copy_node(), part_pos)
+ current:remove_node()
+ else
+ -- break processing if we find normal chapter
+ break
+ end
+ end
+ end
+ end
+
+ -- find the last part in the ncx table. it can contain incorrectly nested chapters
+ local parts = {}
+ for _, navpoint in ipairs(dom:query_selector("navMap navPoint")) do
+ -- we are not able to match just direct navPoint ancestors, so we will use this trick
+ if navpoint:get_parent():get_element_name() == "navMap" then
+ local sec_type, navmark = get_navpoint_info(navpoint)
+ if sec_type == "part" then table.insert(parts, navpoint) end
+ end
+ end
+ if #parts > 0 then
+ -- fix chapters in the last part
+ fix_chapters(parts[#parts])
+ end
+ return dom
+end
+
+local function clean_xml_files()
+ local opf_file = outputdir .. "/content.opf"
+ update_file(opf_file, function(content)
+ -- remove wrong elements from the OPF file
+ -- open opf file and create LuaXML DOM
+ local opf_dom = dom.parse(content)
+ -- remove child elements from elements that don't allow them
+ for _, el in ipairs(opf_dom:query_selector("dc|title, dc|creator")) do
+ -- get text content
+ local text = el:get_text()
+ -- replace element text with a new text node containing original text
+ el._children = {el:create_text_node(text)}
+ end
+ return opf_dom:serialize()
+ end)
+ local ncxfilename = outputdir .. "/" .. outputfilename .. ".ncx"
+ update_file(ncxfilename, function(content)
+ -- remove spurious spaces at the beginning
+ content = content:gsub("^%s*","")
+ local ncx_dom = dom.parse(content)
+ fix_ncx_toc_levels(ncx_dom)
+ -- remove child elements from <text> element
+ for _, el in ipairs(ncx_dom:query_selector("text")) do
+ local text = el:get_text()
+ -- replace element text with a new text node containing original text
+ el._children = {el:create_text_node(text)}
+ end
+ for _, el in ipairs(ncx_dom:query_selector("navPoint")) do
+ -- fix attribute names. this issue is caused by a LuaXML behavior
+ -- that makes all attributes lowercase
+ el._attr["playOrder"] = el._attr["playorder"]
+ el._attr["playorder"] = nil
+ end
+ return ncx_dom:serialize()
+ end)
+
+end
function writeContainer()
make_opf()
+ clean_xml_files()
pack_container()
end
+
local function deldir(path)
for entry in lfs.dir(path) do
if entry~="." and entry~=".." then