summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/context/lua/mtx-epub.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/scripts/context/lua/mtx-epub.lua')
-rw-r--r--Master/texmf-dist/scripts/context/lua/mtx-epub.lua166
1 files changed, 145 insertions, 21 deletions
diff --git a/Master/texmf-dist/scripts/context/lua/mtx-epub.lua b/Master/texmf-dist/scripts/context/lua/mtx-epub.lua
index 70ee7828cee..7d1c157749f 100644
--- a/Master/texmf-dist/scripts/context/lua/mtx-epub.lua
+++ b/Master/texmf-dist/scripts/context/lua/mtx-epub.lua
@@ -18,7 +18,7 @@ if not modules then modules = { } end modules ['mtx-epub'] = {
-- first we need a decent strategy to export them. More information will be
-- available on the wiki.
-local format = string.format
+local format, gsub = string.format, string.gsub
local concat = table.concat
local helpinfo = [[
@@ -60,12 +60,13 @@ local package = [[
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
<dc:title>My Title</dc:title>
<dc:language>en</dc:language>
- <dc:identifier id="%s" />
+ <dc:identifier id="%s" >urn:uuid:%s</dc:identifier>
<dc:creator opf:file-as="Self, My" opf:role="aut">MySelf</dc:creator>
+ <dc:date>%s</dc:date>
</metadata>
<manifest>
- %s
+%s
</manifest>
<spine toc="ncx">
@@ -75,24 +76,65 @@ local package = [[
</package>
]]
--- We need to figure out what is permitted; numbers only seem to give
--- problems is some applications as do names with dashes.
+local item = [[ <item id='%s' href='%s' media-type='%s'/>]]
+
+local toc = [[
+<?xml version="1.0"?>
+
+<!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN" "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">
+
+<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
+
+ <head>
+ <meta name="dtb:uid" content="%s" />
+ <meta name="dtb:depth" content="2" />
+ <meta name="dtb:totalPgeCount" content="0" />
+ <meta name="dtb:maxPageNumber" content="0" />
+ </head>
+
+ <docTitle>
+ <text>%s</text>
+ </docTitle>
+
+ <navMap>
+ <navPoint id="np-1" playOrder="1">
+ <navLabel>
+ <text>start</text>
+ </navLabel>
+ <content src="%s"/>
+ </navPoint>
+ </navMap>
+
+</ncx>
+]]
+
+-- We need to figure out what is permitted. Numbers only seem to give
+-- problems is some applications as do names with dashes. Also the
+-- optional toc is supposed to be there and although id's are by
+-- concept neutral, there are sometimes hard requirements with respect
+-- to their name like ncx and toc.ncx). Maybe we should stick to 3.0
+-- only.
local function dumbid(filename)
-- return (string.gsub(os.uuid(),"%-%","")) -- to be tested
- return file.nameonly(filename)
+ return file.nameonly(filename) .. "-" .. file.extname(filename)
end
local mimetypes = {
xhtml = "application/xhtml+xml",
+ xml = "application/xhtml+xml",
css = "text/css",
+ svg = "image/svg+xml",
+ png = "image/png",
+ jpg = "image/jpeg",
+ ncx = "application/x-dtbncx+xml",
-- default = "text/plain",
}
local idmakers = {
ncx = function(filename) return "ncx" end,
-- css = function(filename) return "stylesheet" end,
- default = function(filename) return dubmid(filename) end,
+ default = function(filename) return dumbid(filename) end,
}
-- specification = {
@@ -106,63 +148,145 @@ local idmakers = {
-- }
-- }
+local function locateimages(oldname,newname,subpath)
+ local data = io.loaddata(oldname)
+ local images = { }
+ local done = gsub(data,"(background%-image *: * url%()(.-)(%))", function(before,name,after)
+ if subpath then
+ name = file.join(subpath,name)
+ end
+ images[#images+1] = name
+ return before .. name .. after
+ end)
+ if newname then
+ io.savedata(done,newname)
+ end
+ return images
+end
+
+local zippers = {
+ {
+ name = "zip",
+ uncompressed = "zip %s -X -0 %s",
+ compressed = "zip %s -X -9 -r %s",
+ },
+ {
+ name = "7zip (7z)",
+ uncompressed = "7z a -tzip -mx0 %s %s",
+ compressed = "7z a -tzip %s %s",
+ },
+}
+
function scripts.epub.make()
local filename = environment.files[1]
- if filename and filename ~= "" then
+ if filename and filename ~= "" and type(filename) == "string" then
filename = file.basename(filename)
local specfile = file.replacesuffix(filename,"specification")
local specification = lfs.isfile(specfile) and dofile(specfile) or { }
- -- inspect(specification)
+-- inspect(specification)
local name = specification.name or file.removesuffix(filename)
- local identifier = specification.identifier or os.uuid()
+ local identifier = specification.identifier or os.uuid(true)
local files = specification.files or { file.addsuffix(filename,"xhtml") }
+ local images = specification.images or { }
local root = specification.root or files[1]
+ -- identifier = gsub(identifier,"[^a-zA-z0-9]","")
+
+ identifier = "BookId" -- weird requirement
+
local epubname = name
local epubpath = file.replacesuffix(name,"tree")
local epubfile = file.replacesuffix(name,"epub")
local epubroot = file.replacesuffix(name,"opf")
+ local epubtoc = "toc.ncx"
+ application.report("creating paths in tree %s",epubpath)
lfs.mkdir(epubpath)
lfs.mkdir(file.join(epubpath,"META-INF"))
lfs.mkdir(file.join(epubpath,"OPS"))
- local used = { }
+ local used = { }
- for i=1,#files do
- local filename = files[i]
+ local function copyone(filename)
local suffix = file.suffix(filename)
local mime = mimetypes[suffix]
if mime then
local idmaker = idmakers[suffix] or idmakers.default
- file.copy(filename,file.join(epubpath,"OPS",filename))
- used[#used+1] = format("<item id='%s' href='%s' media-type='%s'/>",idmaker(filename),filename,mime)
+ local target = file.join(epubpath,"OPS",filename)
+ file.copy(filename,target)
+ application.report("copying %s to %s",filename,target)
+ used[#used+1] = format(item,idmaker(filename),filename,mime)
end
end
+ copyone("toc.ncx")
+
+ local function copythem(files)
+ for i=1,#files do
+ local filename = files[i]
+ if type(filename) == "string" then
+ copyone(filename)
+ end
+ end
+ end
+
+ copythem(files)
+
+ local theimages = { }
+
+ for k, v in table.sortedpairs(images) do
+ theimages[#theimages+1] = k
+ if not lfs.isfile(k) and file.extname(k) == "svg" and file.extname(v) == "pdf" then
+ local command = format("inkscape --export-plain-svg=%s %s",k,v)
+ application.report("running command '%s'\n\n",command)
+ os.execute(command)
+ end
+ end
+
+ copythem(theimages)
+
+ local idmaker = idmakers[file.extname(root)] or idmakers.default
+
container = format(container,epubroot)
- package = format(package,identifier,identifier,concat(used,"\n"),file.removesuffix(root))
+ package = format(package,identifier,identifier,os.uuid(),os.date("!%Y-%m-%dT%H:%M:%SZ"),concat(used,"\n"),idmaker(root))
+ toc = format(toc,identifier,"title",root)
io.savedata(file.join(epubpath,"mimetype"),mimetype)
io.savedata(file.join(epubpath,"META-INF","container.xml"),container)
io.savedata(file.join(epubpath,"OPS",epubroot),package)
+ io.savedata(file.join(epubpath,"OPS",epubtoc),toc)
- lfs.chdir(epubpath)
+ application.report("creating archive\n\n")
+
+ local done = false
+ local list = { }
+ lfs.chdir(epubpath)
os.remove(epubfile)
- os.execute(format("zip %s -0 %s",epubfile,"mimetype"))
- os.execute(format("zip %s -r %s",epubfile,"META-INF"))
- os.execute(format("zip %s -r %s",epubfile,"OPS"))
+ for i=1,#zippers do
+ local zipper = zippers[i]
+ if os.execute(format(zipper.uncompressed,epubfile,"mimetype")) then
+ os.execute(format(zipper.compressed,epubfile,"META-INF"))
+ os.execute(format(zipper.compressed,epubfile,"OPS"))
+ done = zipper.name
+ else
+ list[#list+1] = zipper.name
+ end
+ end
lfs.chdir("..")
- application.report("epub archive: %s",file.join(epubpath,epubfile))
+ if done then
+ application.report("epub archive made using %s: %s",done,file.join(epubpath,epubfile))
+ else
+ application.report("no epub archive made, install one of: %s",concat(list," "))
+ end
end