diff --git a/src/calibre/ebooks/docx/names.py b/src/calibre/ebooks/docx/names.py index db033e6fd5..77ffb6d294 100644 --- a/src/calibre/ebooks/docx/names.py +++ b/src/calibre/ebooks/docx/names.py @@ -83,11 +83,10 @@ def get(x, attr, default=None): return x.attrib.get(expand(attr), default) def ancestor(elem, name): - tag = expand(name) - while elem is not None: - elem = elem.getparent() - if getattr(elem, 'tag', None) == tag: - return elem + try: + return XPath('ancestor::%s[1]' % name)(elem)[0] + except IndexError: + return None def generate_anchor(name, existing): x = y = 'id_' + re.sub(r'[^0-9a-zA-Z_]', '', ascii_text(name)).lstrip('_') diff --git a/src/calibre/ebooks/docx/to_html.py b/src/calibre/ebooks/docx/to_html.py index e2c81edadb..0da4764ac9 100644 --- a/src/calibre/ebooks/docx/to_html.py +++ b/src/calibre/ebooks/docx/to_html.py @@ -16,7 +16,7 @@ from lxml.html.builder import ( from calibre.ebooks.docx.container import DOCX, fromstring from calibre.ebooks.docx.names import ( XPath, is_tag, XML, STYLES, NUMBERING, FONTS, get, generate_anchor, - descendants, ancestor, FOOTNOTES, ENDNOTES, children) + descendants, FOOTNOTES, ENDNOTES, children) from calibre.ebooks.docx.styles import Styles, inherit, PageProperties from calibre.ebooks.docx.numbering import Numbering from calibre.ebooks.docx.fonts import Fonts @@ -308,6 +308,7 @@ class Convert(object): current_anchor = None current_hyperlink = None + hl_xpath = XPath('ancestor::w:hyperlink[1]') for x in descendants(p, 'w:r', 'w:bookmarkStart', 'w:hyperlink'): if x.tag.endswith('}r'): @@ -316,10 +317,10 @@ class Convert(object): (dest if len(dest) == 0 else span).set('id', current_anchor) current_anchor = None if current_hyperlink is not None: - hl = ancestor(x, 'w:hyperlink') - if hl is not None: + try: + hl = hl_xpath(x)[0] self.link_map[hl].append(span) - else: + except IndexError: current_hyperlink = None dest.append(span) self.layers[p].append(x)