mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
DOCX: Hyperlinked images
DOCX Input: Add support for clickable (hyperlinked) images
This commit is contained in:
parent
26e23ac7a6
commit
bbaf2ff574
@ -183,7 +183,7 @@ class DOCX(object):
|
|||||||
root = fromstring(raw)
|
root = fromstring(raw)
|
||||||
for item in root.xpath('//*[local-name()="Relationships"]/*[local-name()="Relationship" and @Type and @Target]'):
|
for item in root.xpath('//*[local-name()="Relationships"]/*[local-name()="Relationship" and @Type and @Target]'):
|
||||||
target = item.get('Target')
|
target = item.get('Target')
|
||||||
if item.get('TargetMode', None) != 'External':
|
if item.get('TargetMode', None) != 'External' and not target.startswith('#'):
|
||||||
target = '/'.join((base, target.lstrip('/')))
|
target = '/'.join((base, target.lstrip('/')))
|
||||||
typ = item.get('Type')
|
typ = item.get('Type')
|
||||||
Id = item.get('Id')
|
Id = item.get('Id')
|
||||||
|
@ -96,6 +96,7 @@ class Images(object):
|
|||||||
self.used = {}
|
self.used = {}
|
||||||
self.names = set()
|
self.names = set()
|
||||||
self.all_images = set()
|
self.all_images = set()
|
||||||
|
self.links = []
|
||||||
|
|
||||||
def __call__(self, relationships_by_id):
|
def __call__(self, relationships_by_id):
|
||||||
self.rid_map = relationships_by_id
|
self.rid_map = relationships_by_id
|
||||||
@ -125,8 +126,18 @@ class Images(object):
|
|||||||
self.all_images.add('images/' + name)
|
self.all_images.add('images/' + name)
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def pic_to_img(self, pic, alt=None):
|
def pic_to_img(self, pic, alt, parent):
|
||||||
name = None
|
name = None
|
||||||
|
link = None
|
||||||
|
for hl in XPath('descendant::a:hlinkClick[@r:id]')(parent):
|
||||||
|
link = {'id':get(hl, 'r:id')}
|
||||||
|
tgt = hl.get('tgtFrame', None)
|
||||||
|
if tgt:
|
||||||
|
link['target'] = tgt
|
||||||
|
title = hl.get('tooltip', None)
|
||||||
|
if title:
|
||||||
|
link['title'] = title
|
||||||
|
|
||||||
for pr in XPath('descendant::pic:cNvPr')(pic):
|
for pr in XPath('descendant::pic:cNvPr')(pic):
|
||||||
name = pr.get('name', None)
|
name = pr.get('name', None)
|
||||||
if name:
|
if name:
|
||||||
@ -138,6 +149,8 @@ class Images(object):
|
|||||||
src = self.generate_filename(rid, name)
|
src = self.generate_filename(rid, name)
|
||||||
img = IMG(src='images/%s' % src)
|
img = IMG(src='images/%s' % src)
|
||||||
img.set('alt', alt or 'Image')
|
img.set('alt', alt or 'Image')
|
||||||
|
if link is not None:
|
||||||
|
self.links.append((img, link))
|
||||||
return img
|
return img
|
||||||
|
|
||||||
def drawing_to_html(self, drawing, page):
|
def drawing_to_html(self, drawing, page):
|
||||||
@ -145,7 +158,7 @@ class Images(object):
|
|||||||
for inline in XPath('./wp:inline')(drawing):
|
for inline in XPath('./wp:inline')(drawing):
|
||||||
style, alt = get_image_properties(inline)
|
style, alt = get_image_properties(inline)
|
||||||
for pic in XPath('descendant::pic:pic')(inline):
|
for pic in XPath('descendant::pic:pic')(inline):
|
||||||
ans = self.pic_to_img(pic, alt)
|
ans = self.pic_to_img(pic, alt, inline)
|
||||||
if ans is not None:
|
if ans is not None:
|
||||||
if style:
|
if style:
|
||||||
ans.set('style', '; '.join('%s: %s' % (k, v) for k, v in style.iteritems()))
|
ans.set('style', '; '.join('%s: %s' % (k, v) for k, v in style.iteritems()))
|
||||||
@ -156,7 +169,7 @@ class Images(object):
|
|||||||
style, alt = get_image_properties(anchor)
|
style, alt = get_image_properties(anchor)
|
||||||
self.get_float_properties(anchor, style, page)
|
self.get_float_properties(anchor, style, page)
|
||||||
for pic in XPath('descendant::pic:pic')(anchor):
|
for pic in XPath('descendant::pic:pic')(anchor):
|
||||||
ans = self.pic_to_img(pic, alt)
|
ans = self.pic_to_img(pic, alt, anchor)
|
||||||
if ans is not None:
|
if ans is not None:
|
||||||
if style:
|
if style:
|
||||||
ans.set('style', '; '.join('%s: %s' % (k, v) for k, v in style.iteritems()))
|
ans.set('style', '; '.join('%s: %s' % (k, v) for k, v in style.iteritems()))
|
||||||
|
@ -442,6 +442,27 @@ class Convert(object):
|
|||||||
continue
|
continue
|
||||||
span.set('href', url)
|
span.set('href', url)
|
||||||
|
|
||||||
|
for img, link in self.images.links:
|
||||||
|
parent = img.getparent()
|
||||||
|
idx = parent.index(img)
|
||||||
|
a = A(img)
|
||||||
|
a.tail, img.tail = img.tail, None
|
||||||
|
parent.insert(idx, a)
|
||||||
|
tgt = link.get('target', None)
|
||||||
|
if tgt:
|
||||||
|
a.set('target', tgt)
|
||||||
|
tt = link.get('title', None)
|
||||||
|
if tt:
|
||||||
|
a.set('title', tt)
|
||||||
|
rid = link['id']
|
||||||
|
if rid in relationships_by_id:
|
||||||
|
dest = relationships_by_id[rid]
|
||||||
|
if dest.startswith('#'):
|
||||||
|
if dest[1:] in self.anchor_map:
|
||||||
|
a.set('href', '#' + self.anchor_map[dest[1:]])
|
||||||
|
else:
|
||||||
|
a.set('href', dest)
|
||||||
|
|
||||||
def convert_run(self, run):
|
def convert_run(self, run):
|
||||||
ans = SPAN()
|
ans = SPAN()
|
||||||
self.object_map[ans] = run
|
self.object_map[ans] = run
|
||||||
|
Loading…
x
Reference in New Issue
Block a user