mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
ToC Editor: When auto-geenrating the table of contents from headings or XPath, if an element is at the top of the file, link only to the file instead of to the element. Fixes #1261099 [[Enhancement]ToC Editor senses when link is to top of file](https://bugs.launchpad.net/calibre/+bug/1261099)
This commit is contained in:
parent
b04b125f34
commit
741bf9577e
@ -484,31 +484,15 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
Perform toc link transforms to alleviate slow loading.
|
Perform toc link transforms to alleviate slow loading.
|
||||||
'''
|
'''
|
||||||
from calibre.ebooks.oeb.base import urldefrag, XPath
|
from calibre.ebooks.oeb.base import urldefrag, XPath
|
||||||
|
from calibre.ebooks.oeb.polish.toc import item_at_top
|
||||||
|
|
||||||
def frag_is_at_top(root, frag):
|
def frag_is_at_top(root, frag):
|
||||||
body = XPath('//h:body')(root)
|
|
||||||
if body:
|
|
||||||
body = body[0]
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
tree = body.getroottree()
|
|
||||||
elem = XPath('//*[@id="%s" or @name="%s"]'%(frag, frag))(root)
|
elem = XPath('//*[@id="%s" or @name="%s"]'%(frag, frag))(root)
|
||||||
if elem:
|
if elem:
|
||||||
elem = elem[0]
|
elem = elem[0]
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
path = tree.getpath(elem)
|
return item_at_top(elem)
|
||||||
for el in body.iterdescendants():
|
|
||||||
epath = tree.getpath(el)
|
|
||||||
if epath == path:
|
|
||||||
break
|
|
||||||
if el.text and el.text.strip():
|
|
||||||
return False
|
|
||||||
if not path.startswith(epath):
|
|
||||||
# Only check tail of non-parent elements
|
|
||||||
if el.tail and el.tail.strip():
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def simplify_toc_entry(toc):
|
def simplify_toc_entry(toc):
|
||||||
if toc.href:
|
if toc.href:
|
||||||
|
@ -211,6 +211,28 @@ def elem_to_toc_text(elem):
|
|||||||
text = _('(Untitled)')
|
text = _('(Untitled)')
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
def item_at_top(elem):
|
||||||
|
try:
|
||||||
|
body = XPath('//h:body')(elem.getroottree().getroot())[0]
|
||||||
|
except (TypeError, IndexError, KeyError, AttributeError):
|
||||||
|
return False
|
||||||
|
tree = body.getroottree()
|
||||||
|
path = tree.getpath(elem)
|
||||||
|
for el in body.iterdescendants(etree.Element):
|
||||||
|
epath = tree.getpath(el)
|
||||||
|
if epath == path:
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
if el.tag.endswith('}img') or (el.text and el.text.strip()):
|
||||||
|
return False
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
if not path.startswith(epath):
|
||||||
|
# Only check tail of non-parent elements
|
||||||
|
if el.tail and el.tail.strip():
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def from_xpaths(container, xpaths):
|
def from_xpaths(container, xpaths):
|
||||||
tocroot = TOC()
|
tocroot = TOC()
|
||||||
xpaths = [XPath(xp) for xp in xpaths]
|
xpaths = [XPath(xp) for xp in xpaths]
|
||||||
@ -249,7 +271,10 @@ def from_xpaths(container, xpaths):
|
|||||||
plvl -= 1
|
plvl -= 1
|
||||||
parent = level_prev[plvl]
|
parent = level_prev[plvl]
|
||||||
lvl = plvl + 1
|
lvl = plvl + 1
|
||||||
dirtied, elem_id = ensure_id(item)
|
if item_at_top(item):
|
||||||
|
dirtied, elem_id = False, None
|
||||||
|
else:
|
||||||
|
dirtied, elem_id = ensure_id(item)
|
||||||
text = elem_to_toc_text(item)
|
text = elem_to_toc_text(item)
|
||||||
item_dirtied = dirtied or item_dirtied
|
item_dirtied = dirtied or item_dirtied
|
||||||
toc = parent.add(text, name, elem_id)
|
toc = parent.add(text, name, elem_id)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user