diff options
Diffstat (limited to 'Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua')
-rwxr-xr-x | Master/texmf-dist/scripts/tex4ebook/exec_epub3.lua | 68 |
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() |