This commit is contained in:
Kovid Goyal 2011-07-22 20:16:05 -06:00
parent 60f1f24e66
commit 34d3ce25aa
3 changed files with 36 additions and 10 deletions

View File

@ -12,6 +12,7 @@ from cStringIO import StringIO
from collections import OrderedDict
from calibre.ebooks import normalize
from calibre.ebook.mobi.writer2 import RECORD_SIZE
from calibre.ebooks.mobi.utils import encint
def utf8_text(text):
@ -37,7 +38,6 @@ def align_block(raw, multiple=4, pad=b'\0'):
if extra == 0: return raw
return raw + pad*(multiple - extra)
class CNCX(object): # {{{
'''
@ -53,17 +53,15 @@ class CNCX(object): # {{{
for item in toc:
if item is self.toc: continue
label = item.title
klass = item.klass
self.strings[item.title] = 0
if opts.mobi_periodical:
self.strings[item.klass] = 0
if item.description:
self.strings[item.description] = 0
if item.author:
self.string[item.author] = 0
self.strings[label] = self.strings[klass] = 0
self.records = []
offset = 0
buf = StringIO()
for key in tuple(self.strings.iterkeys()):
@ -92,17 +90,41 @@ class CNCX(object): # {{{
class Indexer(object):
def __init__(self, serializer, number_of_text_records, opts, oeb):
def __init__(self, serializer, number_of_text_records,
size_of_last_text_record, opts, oeb):
self.serializer = serializer
self.number_of_text_records = number_of_text_records
self.text_size = (RECORD_SIZE * (self.number_of_text_records-1) +
size_of_last_text_record)
self.oeb = oeb
self.log = oeb.log
self.opts = opts
self.cncx = CNCX(oeb.toc, opts)
self.is_periodical = opts.mobi_periodical
self.is_flat_periodical = False
if opts.mobi_periodical:
periodical_node = iter(oeb.toc).next()
sections = tuple(periodical_node)
self.is_flat_periodical = len(sections) == 1
self.records = []
self.cncx = CNCX(oeb.toc, opts)
if self.is_periodical:
self.create_periodical_index()
else:
raise NotImplementedError()
def create_periodical_index(self):
periodical_node = iter(self.oeb.toc).next()
sections = tuple(periodical_node)
periodical_node_offset = self.serializer.body_start_offset
periodical_node_size = (self.serializer.body_end_offset -
periodical_node_offset)
periodical_node_size
sections
def create_header(self):
buf = StringIO()

View File

@ -20,6 +20,7 @@ from calibre.utils.filenames import ascii_filename
from calibre.ebooks.mobi.writer2 import (PALMDOC, UNCOMPRESSED, RECORD_SIZE)
from calibre.ebooks.mobi.utils import (rescale_image, encint,
encode_trailing_data)
from calibre.ebooks.mobi.writer2.indexer import Indexer
EXTH_CODES = {
'creator': 100,
@ -87,6 +88,11 @@ class MobiWriter(object):
# Indexing {{{
def generate_index(self):
self.primary_index_record_idx = None
try:
self.indexer = Indexer(self.serializer, self.last_text_record_idx,
self.opts, self.oeb)
except:
self.log.exception('Failed to generate MOBI index:')
# }}}
def write_uncrossable_breaks(self): # {{{
@ -202,7 +208,6 @@ class MobiWriter(object):
record.write(overlap)
record.write(pack(b'>B', len(overlap)))
self.last_text_record_idx = nrecords
def read_text_record(self, text):
@ -265,8 +270,6 @@ class MobiWriter(object):
# EOF record
self.records.append('\xE9\x8E\x0D\x0A')
self.generate_end_records()
record0 = StringIO()
# The MOBI Header
record0.write(pack(b'>HHIHHHH',

View File

@ -143,6 +143,7 @@ class Serializer(object):
spine.extend([item for item in self.oeb.spine if not item.linear])
for item in spine:
self.serialize_item(item)
self.body_end_offset = buf.tell()
buf.write(b'</body>')
def serialize_item(self, item):