mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement the ability to specify font sizes relative to the rescaled base font size, via class attributes
This commit is contained in:
parent
6fcfff5d68
commit
0ba01714d2
@ -24,6 +24,19 @@ def asfloat(value, default):
|
|||||||
value = default
|
value = default
|
||||||
return float(value)
|
return float(value)
|
||||||
|
|
||||||
|
def dynamic_rescale_factor(node):
|
||||||
|
classes = node.get('class', '').split(' ')
|
||||||
|
classes = [x.replace('calibre_rescale_', '') for x in classes if
|
||||||
|
x.startswith('calibre_rescale_')]
|
||||||
|
if not classes: return None
|
||||||
|
factor = 1.0
|
||||||
|
for x in classes:
|
||||||
|
try:
|
||||||
|
factor *= float(x)/100.
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
return factor
|
||||||
|
|
||||||
|
|
||||||
class KeyMapper(object):
|
class KeyMapper(object):
|
||||||
def __init__(self, sbase, dbase, dkey):
|
def __init__(self, sbase, dbase, dkey):
|
||||||
@ -202,11 +215,19 @@ class CSSFlattener(object):
|
|||||||
if 'bgcolor' in node.attrib:
|
if 'bgcolor' in node.attrib:
|
||||||
cssdict['background-color'] = node.attrib['bgcolor']
|
cssdict['background-color'] = node.attrib['bgcolor']
|
||||||
del node.attrib['bgcolor']
|
del node.attrib['bgcolor']
|
||||||
if not self.context.disable_font_rescaling and \
|
if not self.context.disable_font_rescaling:
|
||||||
'font-size' in cssdict or tag == 'body':
|
_sbase = self.sbase if self.sbase is not None else \
|
||||||
fsize = self.fmap[style['font-size']]
|
self.context.source.fbase
|
||||||
cssdict['font-size'] = "%0.5fem" % (fsize / psize)
|
dyn_rescale = dynamic_rescale_factor(node)
|
||||||
psize = fsize
|
if dyn_rescale is not None:
|
||||||
|
fsize = self.fmap[_sbase]
|
||||||
|
fsize *= dyn_rescale
|
||||||
|
psize = fsize
|
||||||
|
cssdict['font-size'] = '%0.5fpt'%(fsize)
|
||||||
|
elif 'font-size' in cssdict or tag == 'body':
|
||||||
|
fsize = self.fmap[style['font-size']]
|
||||||
|
cssdict['font-size'] = "%0.5fem" % (fsize / psize)
|
||||||
|
psize = fsize
|
||||||
if cssdict:
|
if cssdict:
|
||||||
if self.lineh and self.fbase and tag != 'body':
|
if self.lineh and self.fbase and tag != 'body':
|
||||||
self.clean_edges(cssdict, style, psize)
|
self.clean_edges(cssdict, style, psize)
|
||||||
|
@ -25,14 +25,16 @@ class Jacket(object):
|
|||||||
<title>%(title)s</title>
|
<title>%(title)s</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div style="text-align:center">
|
<div class="calibre_rescale_100">
|
||||||
<h1>%(title)s</h1>
|
<div style="text-align:center">
|
||||||
<h2>%(jacket)s</h2>
|
<h1 class="calibre_rescale_180">%(title)s</h1>
|
||||||
<div>%(series)s</div>
|
<h2 class="calibre_rescale_140">%(jacket)s</h2>
|
||||||
<div>%(tags)s</div>
|
<div class="calibre_rescale_100">%(series)s</div>
|
||||||
</div>
|
<div class="calibre_rescale_100">%(tags)s</div>
|
||||||
<div style="margin-top:2em">
|
</div>
|
||||||
%(comments)s
|
<div style="margin-top:2em" class="calibre_rescale_100">
|
||||||
|
%(comments)s
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -231,23 +231,23 @@ class BasicNewsRecipe(Recipe):
|
|||||||
#: use :member:`extra_css` in your recipe to customize look and feel.
|
#: use :member:`extra_css` in your recipe to customize look and feel.
|
||||||
template_css = u'''
|
template_css = u'''
|
||||||
.article_date {
|
.article_date {
|
||||||
font-size: x-small; color: gray; font-family: monospace;
|
color: gray; font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article_description {
|
.article_description {
|
||||||
font-size: small; font-family: sans; text-indent: 0pt;
|
font-family: sans; text-indent: 0pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.article {
|
a.article {
|
||||||
font-weight: bold; font-size: large;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.feed {
|
a.feed {
|
||||||
font-weight: bold; font-size: large;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
font-family:monospace; font-size:8pt
|
font-family:monospace;
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ from calibre import preferred_encoding, strftime
|
|||||||
|
|
||||||
|
|
||||||
class Template(MarkupTemplate):
|
class Template(MarkupTemplate):
|
||||||
|
|
||||||
def generate(self, *args, **kwargs):
|
def generate(self, *args, **kwargs):
|
||||||
if not kwargs.has_key('style'):
|
if not kwargs.has_key('style'):
|
||||||
kwargs['style'] = ''
|
kwargs['style'] = ''
|
||||||
@ -17,20 +17,20 @@ class Template(MarkupTemplate):
|
|||||||
for arg in args:
|
for arg in args:
|
||||||
if isinstance(arg, basestring) and not isinstance(arg, unicode):
|
if isinstance(arg, basestring) and not isinstance(arg, unicode):
|
||||||
arg = unicode(arg, 'utf-8', 'replace')
|
arg = unicode(arg, 'utf-8', 'replace')
|
||||||
|
|
||||||
return MarkupTemplate.generate(self, *args, **kwargs)
|
return MarkupTemplate.generate(self, *args, **kwargs)
|
||||||
|
|
||||||
class NavBarTemplate(Template):
|
class NavBarTemplate(Template):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Template.__init__(self, u'''\
|
Template.__init__(self, u'''\
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
xml:lang="en"
|
xml:lang="en"
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
xmlns:py="http://genshi.edgewall.org/"
|
xmlns:py="http://genshi.edgewall.org/"
|
||||||
|
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
<style py:if="extra_css" type="text/css">
|
<style py:if="extra_css" type="text/css">
|
||||||
@ -38,7 +38,7 @@ class NavBarTemplate(Template):
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="navbar" style="text-align:${'center' if center else 'left'};">
|
<div class="navbar calibre_rescale_70" style="text-align:${'center' if center else 'left'};">
|
||||||
<hr py:if="bottom" />
|
<hr py:if="bottom" />
|
||||||
<p py:if="bottom" style="text-align:left">
|
<p py:if="bottom" style="text-align:left">
|
||||||
This article was downloaded by <b>${__appname__}</b> from <a href="${url}">${url}</a>
|
This article was downloaded by <b>${__appname__}</b> from <a href="${url}">${url}</a>
|
||||||
@ -50,7 +50,7 @@ class NavBarTemplate(Template):
|
|||||||
<py:if test="art == num - 1 and not bottom">
|
<py:if test="art == num - 1 and not bottom">
|
||||||
| <a href="${prefix}../../feed_${str(feed+1)}/index.html">Next</a>
|
| <a href="${prefix}../../feed_${str(feed+1)}/index.html">Next</a>
|
||||||
</py:if>
|
</py:if>
|
||||||
| <a href="${prefix}../index.html#article_${str(art)}">Section menu</a>
|
| <a href="${prefix}../index.html#article_${str(art)}">Section menu</a>
|
||||||
<py:if test="two_levels">
|
<py:if test="two_levels">
|
||||||
| <a href="${prefix}../../index.html#feed_${str(feed)}">Main menu</a>
|
| <a href="${prefix}../../index.html#feed_${str(feed)}">Main menu</a>
|
||||||
</py:if>
|
</py:if>
|
||||||
@ -64,29 +64,29 @@ class NavBarTemplate(Template):
|
|||||||
</html>
|
</html>
|
||||||
''')
|
''')
|
||||||
|
|
||||||
def generate(self, bottom, feed, art, number_of_articles_in_feed,
|
def generate(self, bottom, feed, art, number_of_articles_in_feed,
|
||||||
two_levels, url, __appname__, prefix='', center=True,
|
two_levels, url, __appname__, prefix='', center=True,
|
||||||
extra_css=None):
|
extra_css=None):
|
||||||
if prefix and not prefix.endswith('/'):
|
if prefix and not prefix.endswith('/'):
|
||||||
prefix += '/'
|
prefix += '/'
|
||||||
return Template.generate(self, bottom=bottom, art=art, feed=feed,
|
return Template.generate(self, bottom=bottom, art=art, feed=feed,
|
||||||
num=number_of_articles_in_feed,
|
num=number_of_articles_in_feed,
|
||||||
two_levels=two_levels, url=url,
|
two_levels=two_levels, url=url,
|
||||||
__appname__=__appname__, prefix=prefix,
|
__appname__=__appname__, prefix=prefix,
|
||||||
center=center, extra_css=extra_css)
|
center=center, extra_css=extra_css)
|
||||||
|
|
||||||
|
|
||||||
class IndexTemplate(Template):
|
class IndexTemplate(Template):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Template.__init__(self, u'''\
|
Template.__init__(self, u'''\
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
xml:lang="en"
|
xml:lang="en"
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
xmlns:py="http://genshi.edgewall.org/"
|
xmlns:py="http://genshi.edgewall.org/"
|
||||||
|
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
@ -99,15 +99,17 @@ class IndexTemplate(Template):
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 class="calibre_recipe_title">${title}</h1>
|
<div class="calibre_rescale_100">
|
||||||
<p style="text-align:right">${date}</p>
|
<h1 class="calibre_recipe_title calibre_rescale_180">${title}</h1>
|
||||||
<ul class="calibre_feed_list">
|
<p style="text-align:right">${date}</p>
|
||||||
<py:for each="i, feed in enumerate(feeds)">
|
<ul class="calibre_feed_list">
|
||||||
<li py:if="feed" id="feed_${str(i)}">
|
<py:for each="i, feed in enumerate(feeds)">
|
||||||
<a class="feed" href="${'feed_%d/index.html'%i}">${feed.title}</a>
|
<li py:if="feed" id="feed_${str(i)}">
|
||||||
</li>
|
<a class="feed calibre_rescale_120" href="${'feed_%d/index.html'%i}">${feed.title}</a>
|
||||||
</py:for>
|
</li>
|
||||||
</ul>
|
</py:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
''')
|
''')
|
||||||
@ -118,19 +120,19 @@ class IndexTemplate(Template):
|
|||||||
date = strftime(datefmt)
|
date = strftime(datefmt)
|
||||||
return Template.generate(self, title=title, date=date, feeds=feeds,
|
return Template.generate(self, title=title, date=date, feeds=feeds,
|
||||||
extra_css=extra_css)
|
extra_css=extra_css)
|
||||||
|
|
||||||
|
|
||||||
class FeedTemplate(Template):
|
class FeedTemplate(Template):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Template.__init__(self, u'''\
|
Template.__init__(self, u'''\
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
xml:lang="en"
|
xml:lang="en"
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
xmlns:py="http://genshi.edgewall.org/"
|
xmlns:py="http://genshi.edgewall.org/"
|
||||||
|
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
@ -143,61 +145,64 @@ class FeedTemplate(Template):
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style="page-break-before:always">
|
<body style="page-break-before:always">
|
||||||
<h2 class="calibre_feed_title">${feed.title}</h2>
|
<div class="calibre_rescale_100">
|
||||||
|
<h2 class="calibre_feed_title calibre_rescale_160">${feed.title}</h2>
|
||||||
<py:if test="getattr(feed, 'image', None)">
|
<py:if test="getattr(feed, 'image', None)">
|
||||||
<div class="calibre_feed_image">
|
<div class="calibre_feed_image">
|
||||||
<img alt="${feed.image_alt}" src="${feed.image_url}" />
|
<img alt="${feed.image_alt}" src="${feed.image_url}" />
|
||||||
</div>
|
</div>
|
||||||
</py:if>
|
</py:if>
|
||||||
<div class="calibre_feed_description" py:if="getattr(feed, 'description', None)">
|
<div class="calibre_feed_description calibre_rescale_80" py:if="getattr(feed, 'description', None)">
|
||||||
${feed.description}<br />
|
${feed.description}<br />
|
||||||
</div>
|
</div>
|
||||||
<ul class="calibre_article_list">
|
<ul class="calibre_article_list">
|
||||||
<py:for each="i, article in enumerate(feed.articles)">
|
<py:for each="i, article in enumerate(feed.articles)">
|
||||||
<li id="${'article_%d'%i}" py:if="getattr(article, 'downloaded', False)" style="padding-bottom:0.5em">
|
<li id="${'article_%d'%i}" py:if="getattr(article, 'downloaded',
|
||||||
<a class="article" href="${article.url}">${article.title}</a>
|
False)" style="padding-bottom:0.5em" class="calibre_rescale_100">
|
||||||
|
<a class="article calibre_rescale_120" href="${article.url}">${article.title}</a>
|
||||||
<span class="article_date">${article.localtime.strftime(" [%a, %d %b %H:%M]")}</span>
|
<span class="article_date">${article.localtime.strftime(" [%a, %d %b %H:%M]")}</span>
|
||||||
<div class="article_decription" py:if="article.summary">
|
<div class="article_decription calibre_rescale_70" py:if="article.summary">
|
||||||
${Markup(cutoff(article.text_summary))}
|
${Markup(cutoff(article.text_summary))}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</py:for>
|
</py:for>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="navbar" style="text-align:center; font-family:monospace; font-size:8pt">
|
<div class="navbar calibre_rescale_70">
|
||||||
| <a href="../index.html">Up one level</a> |
|
| <a href="../index.html">Up one level</a> |
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
''')
|
''')
|
||||||
|
|
||||||
def generate(self, feed, cutoff, extra_css=None):
|
def generate(self, feed, cutoff, extra_css=None):
|
||||||
return Template.generate(self, feed=feed, cutoff=cutoff,
|
return Template.generate(self, feed=feed, cutoff=cutoff,
|
||||||
extra_css=extra_css)
|
extra_css=extra_css)
|
||||||
|
|
||||||
class EmbeddedContent(Template):
|
class EmbeddedContent(Template):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Template.__init__(self, u'''\
|
Template.__init__(self, u'''\
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
xml:lang="en"
|
xml:lang="en"
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
xmlns:py="http://genshi.edgewall.org/"
|
xmlns:py="http://genshi.edgewall.org/"
|
||||||
|
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
<title>${article.title}</title>
|
<title>${article.title}</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h2>${article.title}</h2>
|
<h2>${article.title}</h2>
|
||||||
<div>
|
<div>
|
||||||
${Markup(article.content if len(article.content if article.content else '') > len(article.summary if article.summary else '') else article.summary)}
|
${Markup(article.content if len(article.content if article.content else '') > len(article.summary if article.summary else '') else article.summary)}
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
''')
|
''')
|
||||||
|
|
||||||
def generate(self, article):
|
def generate(self, article):
|
||||||
return Template.generate(self, article=article)
|
return Template.generate(self, article=article)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user