Recognize footnote links

This commit is contained in:
Kovid Goyal 2014-08-08 17:54:46 +05:30
parent f796fc69b1
commit cec5d41697
3 changed files with 70 additions and 2 deletions

View File

@ -29,6 +29,38 @@ inline_styles = (node) ->
return cnode
is_footnote_link = (node, url) ->
if not url or url.substr(0, 'file://'.length).toLowerCase() != 'file://'
return false # Ignore non-local links
# Check for epub:type="noteref", a little complex as we dont operate in XML
# mode
epub_type = node.getAttributeNS("http://www.idpf.org/2007/ops", 'type') or node.getAttribute('epub:type')
if not epub_type
for x in node.attributes # consider any xxx:type="noteref" attribute as marking a note
if x.nodeName and x.nodeValue == 'noteref' and x.nodeName.slice(-':type'.length) == ':type'
epub_type = 'noteref'
break
if epub_type and epub_type.toLowerCase() == 'noteref'
return true
# Check if node or any of its first few parents have vertical-align set
[x, num] = [node, 3]
while x and num > 0
style = window.getComputedStyle(x)
if style.verticalAlign in ['sub', 'super']
return true
x = x.parentNode
num -= 1
# Check if node has a single child with the appropriate css
children = (x for x in node.childNodes when x.nodeType == Node.ELEMENT_NODE)
if children.length == 1
style = window.getComputedStyle(children[0])
if style.verticalAlign in ['sub', 'super']
return true
return false
class CalibreExtract
# This class is a namespace to expose functions via the
# window.calibre_extract object.
@ -47,6 +79,15 @@ class CalibreExtract
cnode = inline_styles(node)
return cnode.outerHTML
get_footnote_data: () =>
ans = {}
for a in document.querySelectorAll('a[href]')
url = a.href # .href returns the full URL while getAttribute() returns the value of the attribute
if not is_footnote_link(a, url)
continue
ans[url] = 1
return JSON.stringify(ans)
if window?
window.calibre_extract = new CalibreExtract()

View File

@ -27,6 +27,7 @@ from calibre.gui2.viewer.image_popup import ImagePopup
from calibre.gui2.viewer.table_popup import TablePopup
from calibre.gui2.viewer.inspector import WebInspector
from calibre.gui2.viewer.gestures import GestureHandler
from calibre.gui2.viewer.footnote import Footnotes
from calibre.ebooks.oeb.display.webview import load_html
from calibre.constants import isxp, iswindows, DEBUG
# }}}
@ -507,6 +508,7 @@ class DocumentView(QWebView): # {{{
self.to_bottom = False
self.document = Document(self.shortcuts, parent=self,
debug_javascript=debug_javascript)
self.footnotes = Footnotes(self.document)
self.setPage(self.document)
self.inspector = WebInspector(self, self.document)
self.manager = None
@ -1306,6 +1308,12 @@ class DocumentView(QWebView): # {{{
return QWebView.event(self, ev)
def mouseReleaseEvent(self, ev):
url = self.document.mainFrame().hitTestContent(ev.pos()).linkUrl()
if url.isValid():
fd = self.footnotes.get_footnote_data(url)
if fd is not None:
print (fd)
return
opos = self.document.ypos
if self.manager is not None:
prev_pos = self.manager.update_page_number()

View File

@ -6,11 +6,30 @@ from __future__ import (unicode_literals, division, absolute_import,
__license__ = 'GPL v3'
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
import json
from PyQt4.Qt import QUrl
class Footnotes(object):
def __init__(self):
def __init__(self, document):
self.document = document
self.clear()
def clear(self):
self.url_cache = {}
self.footnote_data_cache = {}
def get_footnote_data(self, url):
current_url = unicode(self.document.mainFrame().baseUrl().toLocalFile())
if not current_url:
return # Not viewing a local file
fd = self.footnote_data_cache.get(current_url, None)
if fd is None:
raw = self.document.javascript('window.calibre_extract.get_footnote_data()', typ='string')
try:
fd = frozenset(unicode(QUrl(x).toLocalFile()) for x in json.loads(raw))
except Exception:
fd = frozenset()
self.footnote_data_cache[current_url] = fd