mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
MOBI Output: Fix crash when CSS contains invalid font size entries
This commit is contained in:
parent
133d1d761b
commit
5ac7ff5bf2
@ -88,7 +88,7 @@ FONT_SIZE_NAMES = set(['xx-small', 'x-small', 'small', 'medium', 'large',
|
|||||||
class CSSSelector(etree.XPath):
|
class CSSSelector(etree.XPath):
|
||||||
MIN_SPACE_RE = re.compile(r' *([>~+]) *')
|
MIN_SPACE_RE = re.compile(r' *([>~+]) *')
|
||||||
LOCAL_NAME_RE = re.compile(r"(?<!local-)name[(][)] *= *'[^:]+:")
|
LOCAL_NAME_RE = re.compile(r"(?<!local-)name[(][)] *= *'[^:]+:")
|
||||||
|
|
||||||
def __init__(self, css, namespaces=XPNSMAP):
|
def __init__(self, css, namespaces=XPNSMAP):
|
||||||
css = self.MIN_SPACE_RE.sub(r'\1', css)
|
css = self.MIN_SPACE_RE.sub(r'\1', css)
|
||||||
path = css_to_xpath(css)
|
path = css_to_xpath(css)
|
||||||
@ -103,9 +103,9 @@ class CSSSelector(etree.XPath):
|
|||||||
self.css)
|
self.css)
|
||||||
|
|
||||||
|
|
||||||
class Stylizer(object):
|
class Stylizer(object):
|
||||||
STYLESHEETS = WeakKeyDictionary()
|
STYLESHEETS = WeakKeyDictionary()
|
||||||
|
|
||||||
def __init__(self, tree, path, oeb, profile=PROFILES['PRS505']):
|
def __init__(self, tree, path, oeb, profile=PROFILES['PRS505']):
|
||||||
self.oeb = oeb
|
self.oeb = oeb
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
@ -167,7 +167,7 @@ class Stylizer(object):
|
|||||||
self.style(elem)._update_cssdict(cssdict)
|
self.style(elem)._update_cssdict(cssdict)
|
||||||
for elem in xpath(tree, '//h:*[@style]'):
|
for elem in xpath(tree, '//h:*[@style]'):
|
||||||
self.style(elem)._apply_style_attr()
|
self.style(elem)._apply_style_attr()
|
||||||
|
|
||||||
def _fetch_css_file(self, path):
|
def _fetch_css_file(self, path):
|
||||||
hrefs = self.oeb.manifest.hrefs
|
hrefs = self.oeb.manifest.hrefs
|
||||||
if path not in hrefs:
|
if path not in hrefs:
|
||||||
@ -175,7 +175,7 @@ class Stylizer(object):
|
|||||||
data = hrefs[path].data
|
data = hrefs[path].data
|
||||||
data = XHTML_CSS_NAMESPACE + data
|
data = XHTML_CSS_NAMESPACE + data
|
||||||
return ('utf-8', data)
|
return ('utf-8', data)
|
||||||
|
|
||||||
def flatten_rule(self, rule, href, index):
|
def flatten_rule(self, rule, href, index):
|
||||||
results = []
|
results = []
|
||||||
if isinstance(rule, CSSStyleRule):
|
if isinstance(rule, CSSStyleRule):
|
||||||
@ -189,7 +189,7 @@ class Stylizer(object):
|
|||||||
style = self.flatten_style(rule.style)
|
style = self.flatten_style(rule.style)
|
||||||
self.page_rule.update(style)
|
self.page_rule.update(style)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def flatten_style(self, cssstyle):
|
def flatten_style(self, cssstyle):
|
||||||
style = {}
|
style = {}
|
||||||
for prop in cssstyle:
|
for prop in cssstyle:
|
||||||
@ -206,7 +206,7 @@ class Stylizer(object):
|
|||||||
if size in FONT_SIZE_NAMES:
|
if size in FONT_SIZE_NAMES:
|
||||||
style['font-size'] = "%dpt" % self.profile.fnames[size]
|
style['font-size'] = "%dpt" % self.profile.fnames[size]
|
||||||
return style
|
return style
|
||||||
|
|
||||||
def _normalize_edge(self, cssvalue, name):
|
def _normalize_edge(self, cssvalue, name):
|
||||||
style = {}
|
style = {}
|
||||||
if isinstance(cssvalue, CSSValueList):
|
if isinstance(cssvalue, CSSValueList):
|
||||||
@ -228,7 +228,7 @@ class Stylizer(object):
|
|||||||
for edge, value in itertools.izip(edges, values):
|
for edge, value in itertools.izip(edges, values):
|
||||||
style["%s-%s" % (name, edge)] = value
|
style["%s-%s" % (name, edge)] = value
|
||||||
return style
|
return style
|
||||||
|
|
||||||
def _normalize_font(self, cssvalue):
|
def _normalize_font(self, cssvalue):
|
||||||
composition = ('font-style', 'font-variant', 'font-weight',
|
composition = ('font-style', 'font-variant', 'font-weight',
|
||||||
'font-size', 'line-height', 'font-family')
|
'font-size', 'line-height', 'font-family')
|
||||||
@ -275,7 +275,7 @@ class Stylizer(object):
|
|||||||
|
|
||||||
class Style(object):
|
class Style(object):
|
||||||
UNIT_RE = re.compile(r'^(-*[0-9]*[.]?[0-9]*)\s*(%|em|px|mm|cm|in|pt|pc)$')
|
UNIT_RE = re.compile(r'^(-*[0-9]*[.]?[0-9]*)\s*(%|em|px|mm|cm|in|pt|pc)$')
|
||||||
|
|
||||||
def __init__(self, element, stylizer):
|
def __init__(self, element, stylizer):
|
||||||
self._element = element
|
self._element = element
|
||||||
self._profile = stylizer.profile
|
self._profile = stylizer.profile
|
||||||
@ -289,7 +289,7 @@ class Style(object):
|
|||||||
|
|
||||||
def _update_cssdict(self, cssdict):
|
def _update_cssdict(self, cssdict):
|
||||||
self._style.update(cssdict)
|
self._style.update(cssdict)
|
||||||
|
|
||||||
def _apply_style_attr(self):
|
def _apply_style_attr(self):
|
||||||
attrib = self._element.attrib
|
attrib = self._element.attrib
|
||||||
if 'style' not in attrib:
|
if 'style' not in attrib:
|
||||||
@ -301,7 +301,7 @@ class Style(object):
|
|||||||
except CSSSyntaxError:
|
except CSSSyntaxError:
|
||||||
return
|
return
|
||||||
self._style.update(self._stylizer.flatten_style(style))
|
self._style.update(self._stylizer.flatten_style(style))
|
||||||
|
|
||||||
def _has_parent(self):
|
def _has_parent(self):
|
||||||
return (self._element.getparent() is not None)
|
return (self._element.getparent() is not None)
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ class Style(object):
|
|||||||
elif unit == 'in':
|
elif unit == 'in':
|
||||||
result = value * 72.0
|
result = value * 72.0
|
||||||
elif unit == 'pt':
|
elif unit == 'pt':
|
||||||
result = value
|
result = value
|
||||||
elif unit == 'em':
|
elif unit == 'em':
|
||||||
font = font or self.fontSize
|
font = font or self.fontSize
|
||||||
result = value * font
|
result = value * font
|
||||||
@ -365,6 +365,7 @@ class Style(object):
|
|||||||
@property
|
@property
|
||||||
def fontSize(self):
|
def fontSize(self):
|
||||||
def normalize_fontsize(value, base):
|
def normalize_fontsize(value, base):
|
||||||
|
value = value.replace('"', '').replace("'", '')
|
||||||
result = None
|
result = None
|
||||||
factor = None
|
factor = None
|
||||||
if value == 'inherit':
|
if value == 'inherit':
|
||||||
@ -425,7 +426,7 @@ class Style(object):
|
|||||||
result = self._unit_convert(width, base=base)
|
result = self._unit_convert(width, base=base)
|
||||||
self._width = result
|
self._width = result
|
||||||
return self._width
|
return self._width
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def height(self):
|
def height(self):
|
||||||
if self._height is None:
|
if self._height is None:
|
||||||
@ -467,27 +468,27 @@ class Style(object):
|
|||||||
result = 1.2 * self.fontSize
|
result = 1.2 * self.fontSize
|
||||||
self._lineHeight = result
|
self._lineHeight = result
|
||||||
return self._lineHeight
|
return self._lineHeight
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def marginTop(self):
|
def marginTop(self):
|
||||||
return self._unit_convert(
|
return self._unit_convert(
|
||||||
self._get('margin-top'), base=self.height)
|
self._get('margin-top'), base=self.height)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def marginBottom(self):
|
def marginBottom(self):
|
||||||
return self._unit_convert(
|
return self._unit_convert(
|
||||||
self._get('margin-bottom'), base=self.height)
|
self._get('margin-bottom'), base=self.height)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def paddingTop(self):
|
def paddingTop(self):
|
||||||
return self._unit_convert(
|
return self._unit_convert(
|
||||||
self._get('padding-top'), base=self.height)
|
self._get('padding-top'), base=self.height)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def paddingBottom(self):
|
def paddingBottom(self):
|
||||||
return self._unit_convert(
|
return self._unit_convert(
|
||||||
self._get('padding-bottom'), base=self.height)
|
self._get('padding-bottom'), base=self.height)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
items = self._style.items()
|
items = self._style.items()
|
||||||
items.sort()
|
items.sort()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user