Find more NCX ToCs.

Have profile-specific logical CSS font-sizes.
This commit is contained in:
Marshall T. Vandegrift 2008-12-18 22:29:43 -05:00
parent 1f6eda3ff1
commit 4ab6b412c4
2 changed files with 34 additions and 27 deletions

View File

@ -563,13 +563,14 @@ class TOC(object):
class OEBBook(object): class OEBBook(object):
def __init__(self, opfpath=None, container=None, logger=FauxLogger()): def __init__(self, opfpath=None, container=None, logger=FauxLogger()):
if not container: if opfpath and not container:
container = DirContainer(os.path.dirname(opfpath)) container = DirContainer(os.path.dirname(opfpath))
opfpath = os.path.basename(opfpath) opfpath = os.path.basename(opfpath)
self.container = container self.container = container
self.logger = logger self.logger = logger
opf = self._read_opf(opfpath) if opfpath or container:
self._all_from_opf(opf) opf = self._read_opf(opfpath)
self._all_from_opf(opf)
def _convert_opf1(self, opf): def _convert_opf1(self, opf):
nroot = etree.Element(OPF('package'), nroot = etree.Element(OPF('package'),
@ -676,7 +677,10 @@ class OEBBook(object):
def _toc_from_ncx(self, opf): def _toc_from_ncx(self, opf):
result = xpath(opf, '/o2:package/o2:spine/@toc') result = xpath(opf, '/o2:package/o2:spine/@toc')
if not result: if not result:
return False expr = '/o2:package/o2:manifest[@media-type="%s"]/@id'
result = xpath(opf, expr % NCX_MIME)
if len(result) != 1:
return False
id = result[0] id = result[0]
ncx = self.manifest[id].data ncx = self.manifest[id].data
self.manifest.remove(id) self.manifest.remove(id)

View File

@ -16,6 +16,7 @@ import itertools
import types import types
import re import re
import copy import copy
from itertools import izip
import cssutils import cssutils
from cssutils.css import CSSStyleRule, CSSPageRule, CSSStyleDeclaration, \ from cssutils.css import CSSStyleRule, CSSPageRule, CSSStyleDeclaration, \
CSSValueList, cssproperties CSSValueList, cssproperties
@ -25,7 +26,7 @@ from calibre.ebooks.lit.oeb import barename, urlnormalize
from calibre.resources import html_css from calibre.resources import html_css
HTML_CSS_STYLESHEET = cssutils.parseString(html_css) HTML_CSS_STYLESHEET = cssutils.parseString(html_css)
XHTML_CSS_NAMESPACE = "@namespace url(http://www.w3.org/1999/xhtml);\n" XHTML_CSS_NAMESPACE = "@namespace url(%s);\n" % XHTML_NS
INHERITED = set(['azimuth', 'border-collapse', 'border-spacing', INHERITED = set(['azimuth', 'border-collapse', 'border-spacing',
'caption-side', 'color', 'cursor', 'direction', 'elevation', 'caption-side', 'color', 'cursor', 'direction', 'elevation',
@ -82,20 +83,15 @@ DEFAULTS = {'azimuth': 'center', 'background-attachment': 'scroll',
FONT_SIZE_NAMES = set(['xx-small', 'x-small', 'small', 'medium', 'large', FONT_SIZE_NAMES = set(['xx-small', 'x-small', 'small', 'medium', 'large',
'x-large', 'xx-large']) 'x-large', 'xx-large'])
FONT_SIZE_LIST = [('xx-small', 1, 10.), FONT_SIZES = [('xx-small', 1),
('x-small', None, 11.), ('x-small', None),
('small', 2, 13.), ('small', 2),
('medium', 3, 16.), ('medium', 3),
('large', 4, 18.), ('large', 4),
('x-large', 5, 20.), ('x-large', 5),
('xx-large', 6, 22.), ('xx-large', 6),
(None, 7, 24.)] (None, 7)]
FONT_SIZE_BY_NAME = {}
FONT_SIZE_BY_NUM = {}
for name, num, size in FONT_SIZE_LIST:
FONT_SIZE_BY_NAME[name] = size
FONT_SIZE_BY_NUM[num] = size
XPNSMAP = {'h': XHTML_NS,} XPNSMAP = {'h': XHTML_NS,}
def xpath(elem, expr): def xpath(elem, expr):
@ -103,14 +99,20 @@ def xpath(elem, expr):
class Page(object): class Page(object):
def __init__(self, width, height, dpi): def __init__(self, width, height, dpi, fbase, fsizes):
self.width = (float(width) / dpi) * 72. self.width = (float(width) / dpi) * 72.
self.height = (float(height) / dpi) * 72. self.height = (float(height) / dpi) * 72.
self.dpi = float(dpi) self.dpi = float(dpi)
self.fbase = float(fbase)
self.fsizes = []
for (name, num), size in izip(FONT_SIZES, fsizes):
self.fsizes.append((name, num, float(size)))
self.fnames = dict((name, sz) for name, _, sz in self.fsizes if name)
self.fnums = dict((num, sz) for _, num, sz in self.fsizes if num)
class Profiles(object): class Profiles(object):
PRS500 = Page(584, 754, 168.451) PRS505 = Page(584, 754, 168.451, 12, [7.5, 9, 10, 12, 15.5, 20, 22, 24])
PRS505 = PRS500 MSLIT = Page(652, 480, 168.451, 13, [10, 11, 13, 16, 18, 20, 22, 24])
class Stylizer(object): class Stylizer(object):
@ -187,7 +189,7 @@ class Stylizer(object):
size = style['font-size'] size = style['font-size']
if size == 'normal': size = 'medium' if size == 'normal': size = 'medium'
if size in FONT_SIZE_NAMES: if size in FONT_SIZE_NAMES:
style['font-size'] = "%dpt" % FONT_SIZE_BY_NAME[size] style['font-size'] = "%dpt" % self.page.fnames[size]
return style return style
def _normalize_edge(self, cssvalue, name): def _normalize_edge(self, cssvalue, name):
@ -385,18 +387,19 @@ class Style(object):
result = None result = None
factor = None factor = None
if value == 'inherit': if value == 'inherit':
value = 'medium' # We should only see this if the root element
value = self._stylizer.page.fbase
if value in FONT_SIZE_NAMES: if value in FONT_SIZE_NAMES:
result = FONT_SIZE_BY_NAME[value] result = self._stylizer.page.fnames[value]
elif value == 'smaller': elif value == 'smaller':
factor = 1.0/1.2 factor = 1.0/1.2
for _, _, size in FONT_SIZE_LIST: for _, _, size in self._stylizer.page.fsizes:
if base <= size: break if base <= size: break
factor = None factor = None
result = size result = size
elif value == 'larger': elif value == 'larger':
factor = 1.2 factor = 1.2
for _, _, size in reversed(FONT_SIZE_LIST): for _, _, size in reversed(self._stylizer.page.fsizes):
if base >= size: break if base >= size: break
factor = None factor = None
result = size result = size
@ -412,7 +415,7 @@ class Style(object):
styles = self._stylizer._styles styles = self._stylizer._styles
base = styles[self._element.getparent()].fontSize base = styles[self._element.getparent()].fontSize
else: else:
base = normalize_fontsize(DEFAULTS['font-size']) base = self._styles.page.fbase
if 'font-size' in self._style: if 'font-size' in self._style:
size = self._style['font-size'] size = self._style['font-size']
result = normalize_fontsize(size, base) result = normalize_fontsize(size, base)