From e61a1c1b10171a04a6cc9b8759bee78c2a873f8b Mon Sep 17 00:00:00 2001 From: Gonzalo Odiard Date: Fri, 25 Feb 2011 21:04:31 +0000 Subject: Highligh of spoken word in epub backend implemented. Is not working right - Temporary Patch --- diff --git a/epubadapter.py b/epubadapter.py index ab6eb01..38a9991 100644 --- a/epubadapter.py +++ b/epubadapter.py @@ -83,6 +83,7 @@ class EpubViewer(epubview.EpubView): def highlight_next_word(self, word_count): self.current_word = word_count + self._view.highlight_next_word() return True def connect_zoom_handler(self, handler): diff --git a/epubview/epubview.py b/epubview/epubview.py index 4d3a130..5dccad0 100644 --- a/epubview/epubview.py +++ b/epubview/epubview.py @@ -541,6 +541,13 @@ class _View(gtk.HBox): filename = self._paginator.get_file_for_pageno(pageno) if filename != self._loaded_filename: #self._loaded_filename = filename + + # Copy javascript to highligth text to speech + destpath, destname = os.path.split(filename.replace('file://', '')) + shutil.copy('./epubview/highlight_words.js', destpath) + self._insert_js_reference(filename.replace('file://', ''), + destpath) + if filename.endswith('xml'): dest = filename.replace('xml', 'xhtml') shutil.copy(filename.replace('file://', ''), @@ -551,6 +558,16 @@ class _View(gtk.HBox): else: self._scroll_page() + def _insert_js_reference(self, file_name, path): + js_reference = '' + o = open(file_name + '.tmp', 'a') + for line in open(file_name): + line = line.replace('', js_reference + '') + o.write(line + "\n") + o.close() + shutil.copy(file_name + '.tmp', file_name) + def _load_next_file(self): if self._loaded_page == self._pagecount: return diff --git a/epubview/highlight_words.js b/epubview/highlight_words.js new file mode 100644 index 0000000..ffa5e9a --- /dev/null +++ b/epubview/highlight_words.js @@ -0,0 +1,89 @@ + var parentElement; + var actualChild; + var actualWord; + var words; + var originalNode = null; + var modifiedNode = null; + + function trim(s) { + s = ( s || '' ).replace( /^\s+|\s+$/g, '' ); + return s.replace(/[\n\r\t]/g,' '); + } + + + function init() { + parentElement = document.getElementsByTagName("body")[0]; + actualChild = new Array(); + actualWord = 0; + actualChild.push(0); + } + + function highLightNextWordInt() { + var nodeList = parentElement.childNodes; + ini_posi = actualChild[actualChild.length - 1]; + for (var i=ini_posi; i < nodeList.length; i++) { + var node = nodeList[i]; + if ((node.nodeName == "#text") && (trim(node.nodeValue) != '')) { + node_text = trim(node.nodeValue); + words = node_text.split(" "); + if (actualWord < words.length) { + originalNode = document.createTextNode(node.nodeValue); + + prev_text = ''; + for (var p1 = 0; p1 < actualWord; p1++) { + prev_text = prev_text + words[p1] + " "; + } + var textNode1 = document.createTextNode(prev_text); + var textNode2 = document.createTextNode(words[actualWord]+" "); + post_text = ''; + for (var p2 = actualWord + 1; p2 < words.length; p2++) { + post_text = post_text + words[p2] + " "; + } + var textNode3 = document.createTextNode(post_text); + var newParagraph = document.createElement('p'); + var boldNode = document.createElement('b'); + boldNode.appendChild(textNode2); + newParagraph.appendChild(textNode1); + newParagraph.appendChild(boldNode); + newParagraph.appendChild(textNode3); + + parentElement.insertBefore(newParagraph, node); + parentElement.removeChild(node); + modifiedNode = newParagraph; + + actualWord = actualWord + 1; + if (actualWord >= words.length) { + actualChild.pop(); + actualChild[actualChild.length - 1] = actualChild[actualChild.length - 1] + 2; + actualWord = 0; + parentElement = parentElement.parentNode; + } + } + throw "exit"; + } else { + if (node.childNodes.length > 0) { + parentElement = node; + actualChild.push(0); + actualWord = 0; + highLightNextWordInt(); + actualChild.pop(); + } + } + } + return; + } + + + function highLightNextWord() { + if (typeof parentElement == "undefined") { + init(); + } + if (originalNode != null) { + modifiedNode.parentNode.insertBefore(originalNode, modifiedNode); + modifiedNode.parentNode.removeChild(modifiedNode); + } + try { + highLightNextWordInt(); + } catch(er) { + } + } diff --git a/epubview/widgets.py b/epubview/widgets.py index 078ae3b..7af4f31 100644 --- a/epubview/widgets.py +++ b/epubview/widgets.py @@ -34,3 +34,9 @@ class _WebView(webkit.WebView): 'newdiv.style.height = "%dpx";document.body.appendChild(newdiv);' \ % incr) self.execute_script(js) + + def highlight_next_word(self): + ''' + Highlight next word (for text to speech) + ''' + self.execute_script('highLightNextWord();') -- cgit v0.9.1