mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement support for LIT atoms.
This commit is contained in:
parent
440c02a202
commit
2a0cdbd555
@ -115,10 +115,12 @@ class UnBinary(object):
|
|||||||
OPEN_ANGLE_RE = re.compile(r'<<(?![!]--)')
|
OPEN_ANGLE_RE = re.compile(r'<<(?![!]--)')
|
||||||
CLOSE_ANGLE_RE = re.compile(r'(?<!--)>>(?=>>|[^>])')
|
CLOSE_ANGLE_RE = re.compile(r'(?<!--)>>(?=>>|[^>])')
|
||||||
DOUBLE_ANGLE_RE = re.compile(r'([<>])\1')
|
DOUBLE_ANGLE_RE = re.compile(r'([<>])\1')
|
||||||
|
EMPTY_ATOMS = ({},{})
|
||||||
|
|
||||||
def __init__(self, bin, path, manifest={}, map=HTML_MAP):
|
def __init__(self, bin, path, manifest={}, map=HTML_MAP, atoms=EMPTY_ATOMS):
|
||||||
self.manifest = manifest
|
self.manifest = manifest
|
||||||
self.tag_map, self.attr_map, self.tag_to_attr_map = map
|
self.tag_map, self.attr_map, self.tag_to_attr_map = map
|
||||||
|
self.tag_atoms, self.attr_atoms = atoms
|
||||||
self.opf = map is OPF_MAP
|
self.opf = map is OPF_MAP
|
||||||
self.bin = bin
|
self.bin = bin
|
||||||
self.dir = os.path.dirname(path)
|
self.dir = os.path.dirname(path)
|
||||||
@ -196,7 +198,10 @@ class UnBinary(object):
|
|||||||
state = 'get custom length'
|
state = 'get custom length'
|
||||||
continue
|
continue
|
||||||
if flags & FLAG_ATOM:
|
if flags & FLAG_ATOM:
|
||||||
raise LitError('TODO: Atoms not yet implemented')
|
if not self.tag_atoms or tag not in self.tag_atoms:
|
||||||
|
raise LitError("atom tag %d not in atom tag list" % tag)
|
||||||
|
tag_name = self.tag_atoms[tag]
|
||||||
|
current_map = self.attr_atoms
|
||||||
elif tag < len(self.tag_map):
|
elif tag < len(self.tag_map):
|
||||||
tag_name = self.tag_map[tag]
|
tag_name = self.tag_map[tag]
|
||||||
current_map = self.tag_to_attr_map[tag]
|
current_map = self.tag_to_attr_map[tag]
|
||||||
@ -806,6 +811,37 @@ class LitReader(object):
|
|||||||
raise LitError("Failed to completely decompress section")
|
raise LitError("Failed to completely decompress section")
|
||||||
return ''.join(result)
|
return ''.join(result)
|
||||||
|
|
||||||
|
def get_atoms(self, entry):
|
||||||
|
name = '/'.join(('/data', entry.internal, 'atom'))
|
||||||
|
if name not in self.entries:
|
||||||
|
return ({}, {})
|
||||||
|
data = self.get_file(name)
|
||||||
|
nentries, data = u32(data), data[4:]
|
||||||
|
tags = {}
|
||||||
|
for i in xrange(1, nentries + 1):
|
||||||
|
if len(data) <= 1:
|
||||||
|
break
|
||||||
|
size, data = ord(data[0]), data[1:]
|
||||||
|
if size == 0 or len(data) < size:
|
||||||
|
break
|
||||||
|
tags[i], data = data[:size], data[size:]
|
||||||
|
if len(tags) != nentries:
|
||||||
|
self._warn("damaged or invalid atoms tag table")
|
||||||
|
if len(data) < 4:
|
||||||
|
return (tags, {})
|
||||||
|
attrs = {}
|
||||||
|
nentries, data = u32(data), data[4:]
|
||||||
|
for i in xrange(1, nentries + 1):
|
||||||
|
if len(data) <= 4:
|
||||||
|
break
|
||||||
|
size, data = u32(data), data[4:]
|
||||||
|
if size == 0 or len(data) < size:
|
||||||
|
break
|
||||||
|
attrs[i], data = data[:size], data[size:]
|
||||||
|
if len(attrs) != nentries:
|
||||||
|
self._warn("damaged or invalid atoms attributes table")
|
||||||
|
return (tags, attrs)
|
||||||
|
|
||||||
def get_entry_content(self, entry, pretty_print=False):
|
def get_entry_content(self, entry, pretty_print=False):
|
||||||
if 'spine' in entry.state:
|
if 'spine' in entry.state:
|
||||||
name = '/'.join(('/data', entry.internal, 'content'))
|
name = '/'.join(('/data', entry.internal, 'content'))
|
||||||
@ -813,7 +849,8 @@ class LitReader(object):
|
|||||||
raw = self.get_file(name)
|
raw = self.get_file(name)
|
||||||
decl, map = (OPF_DECL, OPF_MAP) \
|
decl, map = (OPF_DECL, OPF_MAP) \
|
||||||
if name == '/meta' else (HTML_DECL, HTML_MAP)
|
if name == '/meta' else (HTML_DECL, HTML_MAP)
|
||||||
content = decl + unicode(UnBinary(raw, path, self.manifest, map))
|
atoms = self.get_atoms(entry)
|
||||||
|
content = decl + unicode(UnBinary(raw, path, self.manifest, map, atoms))
|
||||||
if pretty_print:
|
if pretty_print:
|
||||||
content = self._pretty_print(content)
|
content = self._pretty_print(content)
|
||||||
content = content.encode('utf-8')
|
content = content.encode('utf-8')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user