diff --git a/src/calibre/ebooks/mobi/reader/mobi8.py b/src/calibre/ebooks/mobi/reader/mobi8.py index bf068eb498..dcf2f998b2 100644 --- a/src/calibre/ebooks/mobi/reader/mobi8.py +++ b/src/calibre/ebooks/mobi/reader/mobi8.py @@ -109,7 +109,7 @@ class Mobi8Reader(object): table, cncx = read_index(self.kf8_sections, self.header.othidx, self.header.codec) Item = namedtuple('Item', - 'type title div_frag_num') + 'type title pos_fid') for i, ref_type in enumerate(table.iterkeys()): tag_map = table[ref_type] @@ -119,7 +119,7 @@ class Mobi8Reader(object): if 3 in tag_map.keys(): fileno = tag_map[3][0] if 6 in tag_map.keys(): - fileno = tag_map[6][0] + fileno = tag_map[6] self.guide.append(Item(ref_type.decode(self.header.codec), title, fileno)) @@ -287,23 +287,24 @@ class Mobi8Reader(object): def create_guide(self): guide = Guide() - for ref_type, ref_title, fileno in self.guide: + has_start = False + for ref_type, ref_title, pos_fid in self.guide: try: - elem = self.elems[fileno] - except IndexError: - # Happens for thumbnailstandard in Amazon book samples - continue - fi = self.get_file_info(elem.insert_pos) - idtext = self.get_id_tag(elem.insert_pos).decode(self.header.codec) - linktgt = fi.filename + if len(pos_fid) != 2: + continue + except TypeError: + continue # thumbnailstandard record, ignore it + linktgt, idtext = self.get_id_tag_by_pos_fid(*pos_fid) if idtext: linktgt += b'#' + idtext - g = Guide.Reference('%s/%s'%(fi.type, linktgt), os.getcwdu()) + g = Guide.Reference(linktgt, os.getcwdu()) g.title, g.type = ref_title, ref_type + if g.title == 'start' or g.type == 'text': + has_start = True guide.append(g) so = self.header.exth.start_offset - if so not in {None, NULL_INDEX}: + if so not in {None, NULL_INDEX} and not has_start: fi = self.get_file_info(so) if fi.filename is not None: idtext = self.get_id_tag(so).decode(self.header.codec) diff --git a/src/calibre/ebooks/mobi/writer8/exth.py b/src/calibre/ebooks/mobi/writer8/exth.py index 867e2c3112..b469c01d85 100644 --- a/src/calibre/ebooks/mobi/writer8/exth.py +++ b/src/calibre/ebooks/mobi/writer8/exth.py @@ -153,9 +153,14 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, nrecs += 1 if start_offset is not None: - exth.write(pack(b'>III', EXTH_CODES['startreading'], 12, - start_offset)) - nrecs += 1 + try: + len(start_offset) + except TypeError: + start_offset = [start_offset] + for so in start_offset: + exth.write(pack(b'>III', EXTH_CODES['startreading'], 12, + so)) + nrecs += 1 if num_of_resources is not None: exth.write(pack(b'>III', EXTH_CODES['num_of_resources'], 12, diff --git a/src/calibre/ebooks/mobi/writer8/main.py b/src/calibre/ebooks/mobi/writer8/main.py index f929af80d4..a2148546f8 100644 --- a/src/calibre/ebooks/mobi/writer8/main.py +++ b/src/calibre/ebooks/mobi/writer8/main.py @@ -368,11 +368,11 @@ class KF8Writer(object): if aid is None: continue pos, fid = self.aid_offset_map[aid] - if is_guide_ref_start(ref) and fid == 0: - # If fid != 0 then we cannot represent the start position as a - # single number in the EXTH header, so we do not write it to - # EXTH - self.start_offset = pos + if is_guide_ref_start(ref): + chunk = self.chunk_table[pos] + skel = [s for s in self.skel_table if s.file_number == + chunk.file_number][0] + self.start_offset = skel.start_pos + skel.length + chunk.start_pos + fid self.guide_table.append(GuideRef(ref.title or _('Unknown'), ref.type, (pos, fid)))