mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
AZW3 Input: Add support for page-progression-direction
AZW3 Input: Add support for the page-progression-direction that is used to indicate page turns should happen from right to left. The attribute is passed into EPUB when converting. Fixes #1194766 [Incorrect conversion japanese MOBI](https://bugs.launchpad.net/calibre/+bug/1194766)
This commit is contained in:
parent
03452d2a03
commit
63d133ea5c
@ -1047,6 +1047,14 @@ class OPF(object): # {{{
|
||||
if raw:
|
||||
return raw.rpartition(':')[-1]
|
||||
|
||||
@property
|
||||
def page_progression_direction(self):
|
||||
spine = self.XPath('descendant::*[re:match(name(), "spine", "i")][1]')(self.root)
|
||||
if spine:
|
||||
for k, v in spine[0].attrib.iteritems():
|
||||
if k == 'page-progression-direction' or k.endswith('}page-progression-direction'):
|
||||
return v
|
||||
|
||||
def guess_cover(self):
|
||||
'''
|
||||
Try to guess a cover. Needed for some old/badly formed OPF files.
|
||||
@ -1185,6 +1193,7 @@ class OPFCreator(Metadata):
|
||||
'''
|
||||
Metadata.__init__(self, title='', other=other)
|
||||
self.base_path = os.path.abspath(base_path)
|
||||
self.page_progression_direction = None
|
||||
if self.application_id is None:
|
||||
self.application_id = str(uuid.uuid4())
|
||||
if not isinstance(self.toc, TOC):
|
||||
@ -1356,6 +1365,8 @@ class OPFCreator(Metadata):
|
||||
spine = E.spine()
|
||||
if self.toc is not None:
|
||||
spine.set('toc', 'ncx')
|
||||
if self.page_progression_direction is not None:
|
||||
spine.set('page-progression-direction', self.page_progression_direction)
|
||||
if self.spine is not None:
|
||||
for ref in self.spine:
|
||||
if ref.id is not None:
|
||||
|
@ -20,7 +20,7 @@ from calibre.ebooks.mobi.reader.ncx import read_ncx, build_toc
|
||||
from calibre.ebooks.mobi.reader.markup import expand_mobi8_markup
|
||||
from calibre.ebooks.metadata.opf2 import Guide, OPFCreator
|
||||
from calibre.ebooks.metadata.toc import TOC
|
||||
from calibre.ebooks.mobi.utils import read_font_record
|
||||
from calibre.ebooks.mobi.utils import read_font_record, read_resc_record
|
||||
from calibre.ebooks.oeb.parse_utils import parse_html
|
||||
from calibre.ebooks.oeb.base import XPath, XHTML, xml2text
|
||||
from calibre.utils.imghdr import what
|
||||
@ -65,6 +65,7 @@ class Mobi8Reader(object):
|
||||
self.mobi6_reader, self.log = mobi6_reader, log
|
||||
self.header = mobi6_reader.book_header
|
||||
self.encrypted_fonts = []
|
||||
self.resc_data = {}
|
||||
|
||||
def __call__(self):
|
||||
self.mobi6_reader.check_for_drm()
|
||||
@ -389,9 +390,11 @@ class Mobi8Reader(object):
|
||||
data = sec[0]
|
||||
typ = data[:4]
|
||||
href = None
|
||||
if typ in {b'FLIS', b'FCIS', b'SRCS', b'\xe9\x8e\r\n',
|
||||
b'RESC', b'BOUN', b'FDST', b'DATP', b'AUDI', b'VIDE'}:
|
||||
if typ in {b'FLIS', b'FCIS', b'SRCS', b'\xe9\x8e\r\n', b'BOUN',
|
||||
b'FDST', b'DATP', b'AUDI', b'VIDE'}:
|
||||
pass # Ignore these records
|
||||
elif typ == b'RESC':
|
||||
self.resc_data = read_resc_record(data)
|
||||
elif typ == b'FONT':
|
||||
font = read_font_record(data)
|
||||
href = "fonts/%05d.%s" % (fname_idx, font['ext'])
|
||||
@ -452,6 +455,9 @@ class Mobi8Reader(object):
|
||||
opf.create_manifest_from_files_in([os.getcwdu()], exclude=exclude)
|
||||
opf.create_spine(spine)
|
||||
opf.set_toc(toc)
|
||||
ppd = self.resc_data.get('page-progression-direction', None)
|
||||
if ppd:
|
||||
opf.page_progression_direction = ppd
|
||||
|
||||
with open('metadata.opf', 'wb') as of, open('toc.ncx', 'wb') as ncx:
|
||||
opf.render(of, ncx, 'toc.ncx')
|
||||
|
@ -7,7 +7,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import struct, string, zlib, os
|
||||
import struct, string, zlib, os, re
|
||||
from collections import OrderedDict
|
||||
from io import BytesIO
|
||||
|
||||
@ -393,6 +393,15 @@ def mobify_image(data):
|
||||
data = im.export('gif')
|
||||
return data
|
||||
|
||||
def read_resc_record(data):
|
||||
ans = {}
|
||||
match = re.search(br'''<spine [^>]*page-progression-direction=['"](.+?)['"]''', data)
|
||||
if match is not None:
|
||||
ppd = match.group(1).lower()
|
||||
if ppd in {b'ltr', b'rtl'}:
|
||||
ans['page-progression-direction'] = ppd.decode('ascii')
|
||||
return ans
|
||||
|
||||
# Font records {{{
|
||||
def read_font_record(data, extent=1040):
|
||||
'''
|
||||
|
@ -1210,6 +1210,7 @@ class Spine(object):
|
||||
def __init__(self, oeb):
|
||||
self.oeb = oeb
|
||||
self.items = []
|
||||
self.page_progression_direction = None
|
||||
|
||||
def _linear(self, linear):
|
||||
if isinstance(linear, basestring):
|
||||
@ -1896,4 +1897,6 @@ class OEBBook(object):
|
||||
attrib={'media-type': PAGE_MAP_MIME})
|
||||
spine.attrib['page-map'] = id
|
||||
results[PAGE_MAP_MIME] = (href, self.pages.to_page_map())
|
||||
if self.spine.page_progression_direction in {'ltr', 'rtl'}:
|
||||
spine.attrib['page-progression-direction'] = self.spine.page_progression_direction
|
||||
return results
|
||||
|
@ -330,6 +330,9 @@ class OEBReader(object):
|
||||
if len(spine) == 0:
|
||||
raise OEBError("Spine is empty")
|
||||
self._spine_add_extra()
|
||||
for val in xpath(opf, '/o2:package/o2:spine/@page-progression-direction'):
|
||||
if val in {'ltr', 'rtl'}:
|
||||
spine.page_progression_direction = val
|
||||
|
||||
def _guide_from_opf(self, opf):
|
||||
guide = self.oeb.guide
|
||||
|
Loading…
x
Reference in New Issue
Block a user