mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Edit Book: Check Book: Add checks for links whose fragment (the part after the #) points to a location that does not exist
This commit is contained in:
parent
161bf3bcda
commit
7e6691caa3
@ -63,6 +63,18 @@ class BadDestinationType(BaseError):
|
||||
link_elem.get('href'), link_dest)
|
||||
self.bad_href = link_elem.get('href')
|
||||
|
||||
class BadDestinationFragment(BaseError):
|
||||
|
||||
level = WARN
|
||||
|
||||
def __init__(self, link_source, link_dest, link_elem, fragment):
|
||||
BaseError.__init__(self, _('Link points to a location not present in the target file'), link_source, line=link_elem.sourceline)
|
||||
self.bad_href = link_elem.get('href')
|
||||
self.HELP = _('The link "{0}" points to a location <i>{1}</i> in the file {2} that does not exist.'
|
||||
' You should either remove the location so that the link points to the top of the file,'
|
||||
' or change the link to point to the correct location.').format(
|
||||
self.bad_href, fragment, link_dest)
|
||||
|
||||
class FileLink(BadLink):
|
||||
|
||||
HELP = _('This link uses the file:// URL scheme. This does not work with many ebook readers.'
|
||||
@ -183,14 +195,43 @@ def check_mimetypes(container):
|
||||
a(MimetypeMismatch(container, name, mt, gt))
|
||||
return errors
|
||||
|
||||
def check_link_destination(container, dest_map, name, href, a, errors):
|
||||
tname = container.href_to_name(href, name)
|
||||
if tname and tname in container.mime_map:
|
||||
if container.mime_map[tname] not in OEB_DOCS:
|
||||
errors.append(BadDestinationType(name, tname, a))
|
||||
else:
|
||||
root = container.parsed(tname)
|
||||
if hasattr(root, 'xpath'):
|
||||
if tname not in dest_map:
|
||||
dest_map[tname] = set(root.xpath('//*/@id|//*/@name'))
|
||||
purl = urlparse(href)
|
||||
if purl.fragment and purl.fragment not in dest_map[tname]:
|
||||
errors.append(BadDestinationFragment(name, tname, a, purl.fragment))
|
||||
else:
|
||||
errors.append(BadDestinationType(name, tname, a))
|
||||
|
||||
|
||||
def check_link_destinations(container):
|
||||
' Check destinations of links that point to HTML files '
|
||||
errors = []
|
||||
dest_map = {}
|
||||
opf_type = guess_type('a.opf')
|
||||
ncx_type = guess_type('a.ncx')
|
||||
for name, mt in container.mime_map.iteritems():
|
||||
if mt in OEB_DOCS:
|
||||
for a in container.parsed(name).xpath('//*[local-name()="a" and @href]'):
|
||||
tname = container.href_to_name(a.get('href'), name)
|
||||
if tname and tname in container.mime_map and container.mime_map[tname] not in OEB_DOCS:
|
||||
errors.append(BadDestinationType(name, tname, a))
|
||||
href = a.get('href')
|
||||
check_link_destination(container, dest_map, name, href, a, errors)
|
||||
elif mt == opf_type:
|
||||
for a in container.opf_xpath('//opf:reference[@href]'):
|
||||
href = a.get('href')
|
||||
check_link_destination(container, dest_map, name, href, a, errors)
|
||||
elif mt == ncx_type:
|
||||
for a in container.parsed(name).xpath('//*[local-name() = "content" and @src]'):
|
||||
href = a.get('src')
|
||||
check_link_destination(container, dest_map, name, href, a, errors)
|
||||
|
||||
return errors
|
||||
|
||||
def check_links(container):
|
||||
|
Loading…
x
Reference in New Issue
Block a user