summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua')
-rwxr-xr-xMaster/texmf-dist/scripts/tex4ebook/exec_epub3.lua68
1 files changed, 68 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua b/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua
index eb829284b59..56eff3f341c 100755
--- a/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua
+++ b/Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua
@@ -1,5 +1,6 @@
module(...,package.seeall)
local eb = require("exec_epub")
+local dom = require("luaxml-domobject")
local ext = "xhtml"
local outputdir = nil
@@ -42,6 +43,72 @@ local function makeTOC(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
+ 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 cleanOPF()
-- in epub3, there must be table of contents
-- if there is no toc in the document, we must add generic one
@@ -72,6 +139,7 @@ local function cleanOPF()
-- remove empty guide element
end
content = content:gsub("<guide>%s*</guide>","")
+ content = add_media_overlays(content)
f = io.open(outputdir .. "/" ..opf,"w")
f:write(content)
f:close()