mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement --extra-css
This commit is contained in:
parent
6ec37ff715
commit
b34854b6e4
@ -116,6 +116,7 @@ def add_pipeline_options(parser, plumber):
|
||||
'font_size_mapping',
|
||||
'line_height',
|
||||
'linearize_tables',
|
||||
'extra_css',
|
||||
]
|
||||
),
|
||||
|
||||
|
@ -219,6 +219,14 @@ OptionRecommendation(name='chapter_mark',
|
||||
'to mark chapters.')
|
||||
),
|
||||
|
||||
OptionRecommendation(name='extra_css',
|
||||
recommended_value=None, level=OptionRecommendation.LOW,
|
||||
help=_('Either the path to a CSS stylesheet or raw CSS. '
|
||||
'This CSS will be appended to the style rules from '
|
||||
'the source file, so it can be used to override those '
|
||||
'rules.')
|
||||
),
|
||||
|
||||
|
||||
|
||||
OptionRecommendation(name='read_metadata_from_opf',
|
||||
@ -487,6 +495,9 @@ OptionRecommendation(name='language',
|
||||
else:
|
||||
fkey = map(float, fkey.split(','))
|
||||
|
||||
if self.opts.extra_css and os.path.exists(self.opts.extra_css):
|
||||
self.opts.extra_css = open(self.opts.extra_css, 'rb').read()
|
||||
|
||||
flattener = CSSFlattener(fbase=fbase, fkey=fkey,
|
||||
lineh=self.opts.line_height,
|
||||
untable=self.opts.linearize_tables)
|
||||
|
@ -88,7 +88,7 @@ FONT_SIZE_NAMES = set(['xx-small', 'x-small', 'small', 'medium', 'large',
|
||||
class CSSSelector(etree.XPath):
|
||||
MIN_SPACE_RE = re.compile(r' *([>~+]) *')
|
||||
LOCAL_NAME_RE = re.compile(r"(?<!local-)name[(][)] *= *'[^:]+:")
|
||||
|
||||
|
||||
def __init__(self, css, namespaces=XPNSMAP):
|
||||
css = self.MIN_SPACE_RE.sub(r'\1', css)
|
||||
path = css_to_xpath(css)
|
||||
@ -103,10 +103,10 @@ class CSSSelector(etree.XPath):
|
||||
self.css)
|
||||
|
||||
|
||||
class Stylizer(object):
|
||||
class Stylizer(object):
|
||||
STYLESHEETS = WeakKeyDictionary()
|
||||
|
||||
def __init__(self, tree, path, oeb, profile=PROFILES['PRS505']):
|
||||
|
||||
def __init__(self, tree, path, oeb, profile=PROFILES['PRS505'], extra_css=''):
|
||||
self.oeb = oeb
|
||||
self.profile = profile
|
||||
self.logger = oeb.logger
|
||||
@ -135,6 +135,11 @@ class Stylizer(object):
|
||||
(path, item.href))
|
||||
continue
|
||||
stylesheets.append(sitem.data)
|
||||
if extra_css:
|
||||
text = XHTML_CSS_NAMESPACE + extra_css
|
||||
stylesheet = parser.parseString(text, href=cssname)
|
||||
stylesheet.namespaces['h'] = XHTML_NS
|
||||
stylesheets.append(stylesheet)
|
||||
rules = []
|
||||
index = 0
|
||||
self.stylesheets = set()
|
||||
@ -159,7 +164,7 @@ class Stylizer(object):
|
||||
self.style(elem)._update_cssdict(cssdict)
|
||||
for elem in xpath(tree, '//h:*[@style]'):
|
||||
self.style(elem)._apply_style_attr()
|
||||
|
||||
|
||||
def _fetch_css_file(self, path):
|
||||
hrefs = self.oeb.manifest.hrefs
|
||||
if path not in hrefs:
|
||||
@ -171,7 +176,7 @@ class Stylizer(object):
|
||||
return (None, None)
|
||||
data = item.data.cssText
|
||||
return ('utf-8', data)
|
||||
|
||||
|
||||
def flatten_rule(self, rule, href, index):
|
||||
results = []
|
||||
if isinstance(rule, CSSStyleRule):
|
||||
@ -185,7 +190,7 @@ class Stylizer(object):
|
||||
style = self.flatten_style(rule.style)
|
||||
self.page_rule.update(style)
|
||||
return results
|
||||
|
||||
|
||||
def flatten_style(self, cssstyle):
|
||||
style = {}
|
||||
for prop in cssstyle:
|
||||
@ -202,7 +207,7 @@ class Stylizer(object):
|
||||
if size in FONT_SIZE_NAMES:
|
||||
style['font-size'] = "%dpt" % self.profile.fnames[size]
|
||||
return style
|
||||
|
||||
|
||||
def _normalize_edge(self, cssvalue, name):
|
||||
style = {}
|
||||
if isinstance(cssvalue, CSSValueList):
|
||||
@ -224,7 +229,7 @@ class Stylizer(object):
|
||||
for edge, value in itertools.izip(edges, values):
|
||||
style["%s-%s" % (name, edge)] = value
|
||||
return style
|
||||
|
||||
|
||||
def _normalize_font(self, cssvalue):
|
||||
composition = ('font-style', 'font-variant', 'font-weight',
|
||||
'font-size', 'line-height', 'font-family')
|
||||
@ -271,7 +276,7 @@ class Stylizer(object):
|
||||
|
||||
class Style(object):
|
||||
UNIT_RE = re.compile(r'^(-*[0-9]*[.]?[0-9]*)\s*(%|em|px|mm|cm|in|pt|pc)$')
|
||||
|
||||
|
||||
def __init__(self, element, stylizer):
|
||||
self._element = element
|
||||
self._profile = stylizer.profile
|
||||
@ -285,7 +290,7 @@ class Style(object):
|
||||
|
||||
def _update_cssdict(self, cssdict):
|
||||
self._style.update(cssdict)
|
||||
|
||||
|
||||
def _apply_style_attr(self):
|
||||
attrib = self._element.attrib
|
||||
if 'style' not in attrib:
|
||||
@ -297,7 +302,7 @@ class Style(object):
|
||||
except CSSSyntaxError:
|
||||
return
|
||||
self._style.update(self._stylizer.flatten_style(style))
|
||||
|
||||
|
||||
def _has_parent(self):
|
||||
return (self._element.getparent() is not None)
|
||||
|
||||
@ -346,7 +351,7 @@ class Style(object):
|
||||
elif unit == 'in':
|
||||
result = value * 72.0
|
||||
elif unit == 'pt':
|
||||
result = value
|
||||
result = value
|
||||
elif unit == 'em':
|
||||
font = font or self.fontSize
|
||||
result = value * font
|
||||
@ -421,7 +426,7 @@ class Style(object):
|
||||
result = self._unit_convert(width, base=base)
|
||||
self._width = result
|
||||
return self._width
|
||||
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
if self._height is None:
|
||||
@ -463,27 +468,27 @@ class Style(object):
|
||||
result = 1.2 * self.fontSize
|
||||
self._lineHeight = result
|
||||
return self._lineHeight
|
||||
|
||||
|
||||
@property
|
||||
def marginTop(self):
|
||||
return self._unit_convert(
|
||||
self._get('margin-top'), base=self.height)
|
||||
|
||||
|
||||
@property
|
||||
def marginBottom(self):
|
||||
return self._unit_convert(
|
||||
self._get('margin-bottom'), base=self.height)
|
||||
|
||||
|
||||
@property
|
||||
def paddingTop(self):
|
||||
return self._unit_convert(
|
||||
self._get('padding-top'), base=self.height)
|
||||
|
||||
|
||||
@property
|
||||
def paddingBottom(self):
|
||||
return self._unit_convert(
|
||||
self._get('padding-bottom'), base=self.height)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
items = self._style.items()
|
||||
items.sort()
|
||||
|
@ -116,7 +116,8 @@ class CSSFlattener(object):
|
||||
profile = self.context.source
|
||||
for item in self.oeb.spine:
|
||||
html = item.data
|
||||
stylizer = Stylizer(html, item.href, self.oeb, profile)
|
||||
stylizer = Stylizer(html, item.href, self.oeb, profile,
|
||||
extra_css=self.context.extra_css)
|
||||
self.stylizers[item] = stylizer
|
||||
|
||||
def baseline_node(self, node, stylizer, sizes, csize):
|
||||
|
Loading…
x
Reference in New Issue
Block a user