From 00518bad5ad6bc849d805adbd21eb9592a8b27f0 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Thu, 29 Jan 2009 13:39:45 -0500 Subject: [PATCH] Fix #1687 (1). Point links to the blocks containing their targets. --- src/calibre/ebooks/mobi/mobiml.py | 13 ++++++------- src/calibre/ebooks/mobi/writer.py | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/calibre/ebooks/mobi/mobiml.py b/src/calibre/ebooks/mobi/mobiml.py index ed4465c8be..50d7b298b9 100644 --- a/src/calibre/ebooks/mobi/mobiml.py +++ b/src/calibre/ebooks/mobi/mobiml.py @@ -148,10 +148,6 @@ class MobiMLizer(object): if bstate.pbreak: etree.SubElement(body, MBP('pagebreak')) bstate.pbreak = False - if istate.ids: - for id in istate.ids: - etree.SubElement(body, XHTML('a'), attrib={'id': id}) - istate.ids.clear() bstate.istate = None bstate.anchor = None parent = bstate.nested[-1] if bstate.nested else bstate.body @@ -186,14 +182,17 @@ class MobiMLizer(object): wrapper.attrib['height'] = self.mobimlize_measure(vspace) para.attrib['width'] = self.mobimlize_measure(indent) elif tag == 'table' and vspace > 0: - body = bstate.body vspace = int(round(vspace / self.profile.fbase)) - index = max((0, len(body) - 1)) while vspace > 0: - body.insert(index, etree.Element(XHTML('br'))) + wrapper.addprevious(etree.Element(XHTML('br'))) vspace -= 1 if istate.halign != 'auto': para.attrib['align'] = istate.halign + if istate.ids: + last = bstate.body[-1] + for id in istate.ids: + last.addprevious(etree.Element(XHTML('a'), attrib={'id': id})) + istate.ids.clear() pstate = bstate.istate if tag in CONTENT_TAGS: bstate.inline = para diff --git a/src/calibre/ebooks/mobi/writer.py b/src/calibre/ebooks/mobi/writer.py index 92ecdf1a46..49f4e076a4 100644 --- a/src/calibre/ebooks/mobi/writer.py +++ b/src/calibre/ebooks/mobi/writer.py @@ -197,6 +197,7 @@ class Serializer(object): def serialize_body(self): buffer = self.buffer + self.anchor_offset = buffer.tell() buffer.write('') # CybookG3 'Start Reading' link if 'text' in self.oeb.guide: @@ -225,14 +226,17 @@ class Serializer(object): or namespace(elem.tag) not in nsrmap: return tag = prefixname(elem.tag, nsrmap) - for attr in ('name', 'id'): - if attr in elem.attrib: - href = '#'.join((item.href, elem.attrib[attr])) - self.id_offsets[href] = buffer.tell() - del elem.attrib[attr] - if tag == 'a' and not elem.attrib \ - and not len(elem) and not elem.text: + # Previous layers take care of @name + id = elem.attrib.pop('id', None) + if id is not None: + href = '#'.join((item.href, id)) + offset = self.anchor_offset or buffer.tell() + self.id_offsets[href] = offset + if self.anchor_offset is not None and \ + tag == 'a' and not elem.attrib and \ + not len(elem) and not elem.text: return + self.anchor_offset = buffer.tell() buffer.write('<') buffer.write(tag) if elem.attrib: @@ -257,10 +261,12 @@ class Serializer(object): if elem.text or len(elem) > 0: buffer.write('>') if elem.text: + self.anchor_offset = None self.serialize_text(elem.text) for child in elem: self.serialize_elem(child, item) if child.tail: + self.anchor_offset = None self.serialize_text(child.tail) buffer.write('' % tag) else: