mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from custcol trunk
This commit is contained in:
commit
064bda5feb
@ -4,6 +4,70 @@
|
|||||||
# for important features/bug fixes.
|
# for important features/bug fixes.
|
||||||
# Also, each release can have new and improved recipes.
|
# Also, each release can have new and improved recipes.
|
||||||
|
|
||||||
|
- version: 0.6.54
|
||||||
|
date: 2010-05-21
|
||||||
|
|
||||||
|
new features:
|
||||||
|
- title: "EPUB Output: Add option to toggle preserving the aspect ratio of the cover."
|
||||||
|
type: major
|
||||||
|
description: >
|
||||||
|
"By default calibre creates an SVG based cover that scales with the screen size of the reader used to view it. Previosuly this scaling
|
||||||
|
was limited to preserve the aspect ratio of the image. This would often result in white borders at the sides or top and bottom of the image.
|
||||||
|
No, by default, calibre will setup the cover to not preserve aspect ratio, doing away with the white borders. The downside is that if the
|
||||||
|
aspect ratio of the cover is very different from the reader, it will look distorted. The old behavior can be restored via
|
||||||
|
Preferences->Conversion->EPUB Output."
|
||||||
|
|
||||||
|
- title: "Conversion pipeline: calibre will now automatically replace all ligatures in the input document."
|
||||||
|
type: major
|
||||||
|
description: >
|
||||||
|
"Conversion pipeline: calibre will now automatically replace all ligatures in the input document with the normal character
|
||||||
|
sequence they are meant to represent. This is because most readers lack the font support to display ligatures.
|
||||||
|
This can be turned off via an option under Look & Feel, in the Conversion settings."
|
||||||
|
|
||||||
|
- title: "Support for the iPapyrus and Newsmy readers and the Sony Ericsson XPERIA X10"
|
||||||
|
|
||||||
|
- title: "PDF Output: Set the first page to the cover."
|
||||||
|
tickets: [5581]
|
||||||
|
|
||||||
|
bug fixes:
|
||||||
|
- title: "Conversion pipeline: Handle input documents with no text. Allows conversion of MOBI files tha are only a sequence of images."
|
||||||
|
tickets: [5554]
|
||||||
|
|
||||||
|
- title: "Fix text justification control not working with translated version of calibre"
|
||||||
|
tickets: [5551]
|
||||||
|
|
||||||
|
- title: "HTML Input: Encoding detection fixed for <meta> tags that have newlines in their content attributes"
|
||||||
|
tickets: [5567]
|
||||||
|
|
||||||
|
- title: "EPUB Input: Handle malformed UUID in EPUB with obfuscated fonts."
|
||||||
|
tickets: [5552]
|
||||||
|
|
||||||
|
- title: "Don't resort when editing columns in the main GUI"
|
||||||
|
|
||||||
|
- title: "Fix regression in Kobo driver that caused it to only detect books in the root directory of the device"
|
||||||
|
|
||||||
|
new recipes:
|
||||||
|
- title: La Stampa and Libero
|
||||||
|
author: Gabriele Marini
|
||||||
|
|
||||||
|
- title: Der Tagesspiegel
|
||||||
|
author: ipaschke
|
||||||
|
|
||||||
|
- title: EMG and Agro Gerilla
|
||||||
|
author: Darko Miletic
|
||||||
|
|
||||||
|
- title: American Prospect, FactCheck and PolitiFact
|
||||||
|
author: Michael Heinz
|
||||||
|
|
||||||
|
improved recipes:
|
||||||
|
- Times Online
|
||||||
|
- The Atlantic
|
||||||
|
- Il Messagero
|
||||||
|
- Leggo
|
||||||
|
- Instapaper
|
||||||
|
- New York Review of Books
|
||||||
|
- NIN Online
|
||||||
|
|
||||||
- version: 0.6.53
|
- version: 0.6.53
|
||||||
date: 2010-05-15
|
date: 2010-05-15
|
||||||
|
|
||||||
@ -157,7 +221,7 @@
|
|||||||
new features:
|
new features:
|
||||||
- title: "Add merge book feature"
|
- title: "Add merge book feature"
|
||||||
type: major
|
type: major
|
||||||
desc: >
|
description: >
|
||||||
"You can now merge multiple books into a single book, by clicking the arrow next to the edit meta information button.
|
"You can now merge multiple books into a single book, by clicking the arrow next to the edit meta information button.
|
||||||
Meta information from the books will be merged as well as individual book files in different formats"
|
Meta information from the books will be merged as well as individual book files in different formats"
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
'''
|
'''
|
||||||
theatlantic.com
|
theatlantic.com
|
||||||
'''
|
'''
|
||||||
import string
|
import string, re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import Tag, NavigableString
|
from calibre.ebooks.BeautifulSoup import Tag, NavigableString
|
||||||
@ -23,6 +23,8 @@ class TheAtlantic(BasicNewsRecipe):
|
|||||||
remove_tags = [dict(id=['header', 'printAds', 'pageControls'])]
|
remove_tags = [dict(id=['header', 'printAds', 'pageControls'])]
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
|
|
||||||
|
preprocess_regexps = [(re.compile(r'<!--.*?-->', re.DOTALL), lambda m: '')]
|
||||||
|
|
||||||
|
|
||||||
def print_version(self, url):
|
def print_version(self, url):
|
||||||
return url.replace('/archive/', '/print/')
|
return url.replace('/archive/', '/print/')
|
||||||
|
@ -22,7 +22,7 @@ class Economist(BasicNewsRecipe):
|
|||||||
' Needs a subscription from ')+INDEX
|
' Needs a subscription from ')+INDEX
|
||||||
|
|
||||||
oldest_article = 7.0
|
oldest_article = 7.0
|
||||||
cover_url = 'http://www.economist.com/images/covers/currentcovereu_large.jpg'
|
cover_url = 'http://www.economist.com/images/covers/currentcoverus_large.jpg'
|
||||||
remove_tags = [dict(name=['script', 'noscript', 'title', 'iframe', 'cf_floatingcontent']),
|
remove_tags = [dict(name=['script', 'noscript', 'title', 'iframe', 'cf_floatingcontent']),
|
||||||
dict(attrs={'class':['dblClkTrk']})]
|
dict(attrs={'class':['dblClkTrk']})]
|
||||||
remove_tags_before = dict(name=lambda tag: tag.name=='title' and tag.parent.name=='body')
|
remove_tags_before = dict(name=lambda tag: tag.name=='title' and tag.parent.name=='body')
|
||||||
|
@ -15,7 +15,7 @@ class Economist(BasicNewsRecipe):
|
|||||||
' Much slower than the subscription based version.')
|
' Much slower than the subscription based version.')
|
||||||
|
|
||||||
oldest_article = 7.0
|
oldest_article = 7.0
|
||||||
cover_url = 'http://www.economist.com/images/covers/currentcovereu_large.jpg'
|
cover_url = 'http://www.economist.com/images/covers/currentcoverus_large.jpg'
|
||||||
remove_tags = [dict(name=['script', 'noscript', 'title', 'iframe', 'cf_floatingcontent']),
|
remove_tags = [dict(name=['script', 'noscript', 'title', 'iframe', 'cf_floatingcontent']),
|
||||||
dict(attrs={'class':['dblClkTrk']})]
|
dict(attrs={'class':['dblClkTrk']})]
|
||||||
remove_tags_before = dict(name=lambda tag: tag.name=='title' and tag.parent.name=='body')
|
remove_tags_before = dict(name=lambda tag: tag.name=='title' and tag.parent.name=='body')
|
||||||
|
86
resources/recipes/tagesspiegel.recipe
Normal file
86
resources/recipes/tagesspiegel.recipe
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010 Ingo Paschke <ipaschke@gmail.com>'
|
||||||
|
|
||||||
|
'''
|
||||||
|
Fetch Tagesspiegel.
|
||||||
|
'''
|
||||||
|
import string, re
|
||||||
|
from calibre import strftime
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class TagesspiegelRSS(BasicNewsRecipe):
|
||||||
|
title = u'Der Tagesspiegel'
|
||||||
|
__author__ = 'ipaschke'
|
||||||
|
language = 'de'
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
|
||||||
|
extra_css = '''
|
||||||
|
.hcf-overline{color:#990000; font-family:Arial,Helvetica,sans-serif;font-size:xx-small;display:block}
|
||||||
|
.hcf-teaser{font-family:Verdana,Arial,Helvetica;font-size:x-small;margin-top:0}
|
||||||
|
h1{font-family:Arial,Helvetica,sans-serif;font-size:large;clear:right;}
|
||||||
|
.hcf-caption{color:#666666; font-family:Arial,Helvetica,sans-serif;font-size:xx-small;}
|
||||||
|
.hcf-copyright{color:#666666; font-family:Arial,Helvetica,sans-serif;font-size:xx-small;}
|
||||||
|
.hcf-article{font-family:Arial,Helvetica;font-size:x-small}
|
||||||
|
.quote{font-family:Georgia,Palatino,Palatino Linotype,FreeSerif,serif;font-size:x-small}
|
||||||
|
.quote .cite{font-family:Georgia,Palatino,Palatino Linotype,FreeSerif,serif;font-size:xx-small}
|
||||||
|
.hcf-inline-left{float:left;margin-right:15px;position:relative;}
|
||||||
|
.hcf-inline-right{float:right;margin-right:15px;position:relative;}
|
||||||
|
.hcf-smart-box{font-family: Arial, Helvetica, sans-serif; font-size: xx-small; margin: 0px 15px 8px 0px; width: 300px;}
|
||||||
|
'''
|
||||||
|
|
||||||
|
no_stylesheets = True
|
||||||
|
no_javascript = True
|
||||||
|
remove_empty_feeds = True
|
||||||
|
encoding = 'utf-8'
|
||||||
|
|
||||||
|
keep_only_tags = dict(name='div', attrs={'class':["hcf-article"]})
|
||||||
|
remove_tags = [
|
||||||
|
dict(name='link'), dict(name='iframe'),dict(name='style'),dict(name='meta'),dict(name='button'),
|
||||||
|
dict(name='div', attrs={'class':["hcf-jump-to-comments","hcf-clear","hcf-magnify hcf-media-control"] }),
|
||||||
|
dict(name='span', attrs={'class':["hcf-mainsearch",] }),
|
||||||
|
dict(name='ul', attrs={'class':["hcf-tools"] }),
|
||||||
|
]
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
soup = self.index_to_soup('http://www.tagesspiegel.de/zeitung/')
|
||||||
|
|
||||||
|
def feed_title(div):
|
||||||
|
return ''.join(div.findAll(text=True, recursive=False)).strip()
|
||||||
|
|
||||||
|
articles = {}
|
||||||
|
key = None
|
||||||
|
ans = []
|
||||||
|
|
||||||
|
for div in soup.findAll(True, attrs={'class':['hcf-teaser', 'hcf-header', 'story headline']}):
|
||||||
|
|
||||||
|
if div['class'] == 'hcf-header':
|
||||||
|
key = string.capwords(feed_title(div.em.a))
|
||||||
|
articles[key] = []
|
||||||
|
ans.append(key)
|
||||||
|
|
||||||
|
elif div['class'] == 'hcf-teaser' and getattr(div.contents[0],'name','') == 'h2':
|
||||||
|
a = div.find('a', href=True)
|
||||||
|
if not a:
|
||||||
|
continue
|
||||||
|
url = 'http://www.tagesspiegel.de' + a['href']
|
||||||
|
title = self.tag_to_string(a, use_alt=True).strip()
|
||||||
|
description = ''
|
||||||
|
pubdate = strftime('%a, %d %b')
|
||||||
|
summary = div.find('p', attrs={'class':'hcf-teaser'})
|
||||||
|
if summary:
|
||||||
|
description = self.tag_to_string(summary, use_alt=False)
|
||||||
|
|
||||||
|
feed = key if key is not None else 'Uncategorized'
|
||||||
|
if not articles.has_key(feed):
|
||||||
|
articles[feed] = []
|
||||||
|
if not 'podcasts' in url:
|
||||||
|
articles[feed].append(
|
||||||
|
dict(title=title, url=url, date=pubdate,
|
||||||
|
description=re.sub('mehr$', '', description),
|
||||||
|
content=''))
|
||||||
|
|
||||||
|
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
||||||
|
|
||||||
|
return ans
|
||||||
|
|
@ -5,6 +5,7 @@ __copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
|||||||
'''
|
'''
|
||||||
timesonline.co.uk
|
timesonline.co.uk
|
||||||
'''
|
'''
|
||||||
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import Tag
|
from calibre.ebooks.BeautifulSoup import Tag
|
||||||
@ -26,6 +27,8 @@ class Timesonline(BasicNewsRecipe):
|
|||||||
recursions = 9
|
recursions = 9
|
||||||
match_regexps = [r'http://www.timesonline.co.uk/.*page=[2-9]']
|
match_regexps = [r'http://www.timesonline.co.uk/.*page=[2-9]']
|
||||||
|
|
||||||
|
preprocess_regexps = [(re.compile(r'<!--.*?-->', re.DOTALL), lambda m: '')]
|
||||||
|
|
||||||
keep_only_tags = [
|
keep_only_tags = [
|
||||||
dict(name='div', attrs= {'id':['region-column1and2-layout2']}),
|
dict(name='div', attrs= {'id':['region-column1and2-layout2']}),
|
||||||
{'class' : ['subheading']},
|
{'class' : ['subheading']},
|
||||||
@ -76,8 +79,7 @@ class Timesonline(BasicNewsRecipe):
|
|||||||
soup = self.index_to_soup(index)
|
soup = self.index_to_soup(index)
|
||||||
link_item = soup.find(name = 'div',attrs ={'class': "float-left margin-right-15"})
|
link_item = soup.find(name = 'div',attrs ={'class': "float-left margin-right-15"})
|
||||||
if link_item:
|
if link_item:
|
||||||
cover_url = 'http://www.timesonline.co.uk' + link_item.img['src']
|
cover_url = link_item.img['src']
|
||||||
print cover_url
|
|
||||||
return cover_url
|
return cover_url
|
||||||
|
|
||||||
def get_article_url(self, article):
|
def get_article_url(self, article):
|
||||||
@ -85,9 +87,9 @@ class Timesonline(BasicNewsRecipe):
|
|||||||
|
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
soup.html['xml:lang'] = self.lang
|
soup.html['xml:lang'] = self.language
|
||||||
soup.html['lang'] = self.lang
|
soup.html['lang'] = self.language
|
||||||
mlang = Tag(soup,'meta',[("http-equiv","Content-Language"),("content",self.lang)])
|
mlang = Tag(soup,'meta',[("http-equiv","Content-Language"),("content",self.language)])
|
||||||
mcharset = Tag(soup,'meta',[("http-equiv","Content-Type"),("content","text/html; charset=ISO-8859-1")])
|
mcharset = Tag(soup,'meta',[("http-equiv","Content-Type"),("content","text/html; charset=ISO-8859-1")])
|
||||||
soup.head.insert(0,mlang)
|
soup.head.insert(0,mlang)
|
||||||
soup.head.insert(1,mcharset)
|
soup.head.insert(1,mcharset)
|
||||||
|
@ -46,8 +46,155 @@ block_level_tags = (
|
|||||||
'ul',
|
'ul',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class CoverManager(object):
|
||||||
|
|
||||||
class EPUBOutput(OutputFormatPlugin):
|
'''
|
||||||
|
Manage the cover in the output document. Requires the opts object to have
|
||||||
|
the attributes:
|
||||||
|
|
||||||
|
no_svg_cover
|
||||||
|
no_default_epub_cover
|
||||||
|
preserve_cover_aspect_ratio
|
||||||
|
'''
|
||||||
|
|
||||||
|
NONSVG_TITLEPAGE_COVER = '''\
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<meta name="calibre:cover" content="true" />
|
||||||
|
<title>Cover</title>
|
||||||
|
<style type="text/css" title="override_css">
|
||||||
|
@page {padding: 0pt; margin:0pt}
|
||||||
|
body { text-align: center; padding:0pt; margin: 0pt; }
|
||||||
|
div { padding:0pt; margin: 0pt; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<img src="%s" alt="cover" style="height: 100%%" />
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
'''
|
||||||
|
|
||||||
|
TITLEPAGE_COVER = '''\
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<meta name="calibre:cover" content="true" />
|
||||||
|
<title>Cover</title>
|
||||||
|
<style type="text/css" title="override_css">
|
||||||
|
@page {padding: 0pt; margin:0pt}
|
||||||
|
body { text-align: center; padding:0pt; margin: 0pt; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
width="100%%" height="100%%" viewBox="0 0 600 800"
|
||||||
|
preserveAspectRatio="__ar__">
|
||||||
|
<image width="600" height="800" xlink:href="%s"/>
|
||||||
|
</svg>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def default_cover(self):
|
||||||
|
'''
|
||||||
|
Create a generic cover for books that dont have a cover
|
||||||
|
'''
|
||||||
|
from calibre.utils.pil_draw import draw_centered_text
|
||||||
|
from calibre.ebooks.metadata import authors_to_string
|
||||||
|
if self.opts.no_default_epub_cover:
|
||||||
|
return None
|
||||||
|
self.log('Generating default cover')
|
||||||
|
m = self.oeb.metadata
|
||||||
|
title = unicode(m.title[0])
|
||||||
|
authors = [unicode(x) for x in m.creator if x.role == 'aut']
|
||||||
|
|
||||||
|
import cStringIO
|
||||||
|
cover_file = cStringIO.StringIO()
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
Image, ImageDraw, ImageFont
|
||||||
|
except ImportError:
|
||||||
|
import Image, ImageDraw, ImageFont
|
||||||
|
font_path = P('fonts/liberation/LiberationSerif-Bold.ttf')
|
||||||
|
app = '['+__appname__ +' '+__version__+']'
|
||||||
|
|
||||||
|
COVER_WIDTH, COVER_HEIGHT = 590, 750
|
||||||
|
img = Image.new('RGB', (COVER_WIDTH, COVER_HEIGHT), 'white')
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
# Title
|
||||||
|
font = ImageFont.truetype(font_path, 44)
|
||||||
|
bottom = draw_centered_text(img, draw, font, title, 15, ysep=9)
|
||||||
|
# Authors
|
||||||
|
bottom += 14
|
||||||
|
font = ImageFont.truetype(font_path, 32)
|
||||||
|
authors = authors_to_string(authors)
|
||||||
|
bottom = draw_centered_text(img, draw, font, authors, bottom, ysep=7)
|
||||||
|
# Vanity
|
||||||
|
font = ImageFont.truetype(font_path, 28)
|
||||||
|
width, height = draw.textsize(app, font=font)
|
||||||
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
|
top = COVER_HEIGHT - height - 15
|
||||||
|
draw.text((left, top), app, fill=(0,0,0), font=font)
|
||||||
|
# Logo
|
||||||
|
logo = Image.open(I('library.png'), 'r')
|
||||||
|
width, height = logo.size
|
||||||
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
|
top = max(int((COVER_HEIGHT - height)/2.), 0)
|
||||||
|
img.paste(logo, (left, max(bottom, top)))
|
||||||
|
img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE)
|
||||||
|
|
||||||
|
img.convert('RGB').save(cover_file, 'JPEG')
|
||||||
|
cover_file.flush()
|
||||||
|
id, href = self.oeb.manifest.generate('cover_image', 'cover_image.jpg')
|
||||||
|
item = self.oeb.manifest.add(id, href, guess_type('t.jpg')[0],
|
||||||
|
data=cover_file.getvalue())
|
||||||
|
m.clear('cover')
|
||||||
|
m.add('cover', item.id)
|
||||||
|
|
||||||
|
return item.href
|
||||||
|
except:
|
||||||
|
self.log.exception('Failed to generate default cover')
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def insert_cover(self):
|
||||||
|
from calibre.ebooks.oeb.base import urldefrag
|
||||||
|
from calibre import guess_type
|
||||||
|
g, m = self.oeb.guide, self.oeb.manifest
|
||||||
|
item = None
|
||||||
|
ar = 'xMidYMid meet' if self.opts.preserve_cover_aspect_ratio else \
|
||||||
|
'none'
|
||||||
|
svg_template = self.TITLEPAGE_COVER.replace('__ar__', ar)
|
||||||
|
if 'titlepage' not in g:
|
||||||
|
if 'cover' in g:
|
||||||
|
href = g['cover'].href
|
||||||
|
else:
|
||||||
|
href = self.default_cover()
|
||||||
|
if href is not None:
|
||||||
|
templ = self.NONSVG_TITLEPAGE_COVER if self.opts.no_svg_cover \
|
||||||
|
else svg_template
|
||||||
|
tp = templ%unquote(href)
|
||||||
|
id, href = m.generate('titlepage', 'titlepage.xhtml')
|
||||||
|
item = m.add(id, href, guess_type('t.xhtml')[0],
|
||||||
|
data=etree.fromstring(tp))
|
||||||
|
else:
|
||||||
|
item = self.oeb.manifest.hrefs[
|
||||||
|
urldefrag(self.oeb.guide['titlepage'].href)[0]]
|
||||||
|
if item is not None:
|
||||||
|
self.oeb.spine.insert(0, item, True)
|
||||||
|
if 'cover' not in self.oeb.guide.refs:
|
||||||
|
self.oeb.guide.add('cover', 'Title Page', 'a')
|
||||||
|
self.oeb.guide.refs['cover'].href = item.href
|
||||||
|
if 'titlepage' in self.oeb.guide.refs:
|
||||||
|
self.oeb.guide.refs['titlepage'].href = item.href
|
||||||
|
|
||||||
|
|
||||||
|
class EPUBOutput(OutputFormatPlugin, CoverManager):
|
||||||
|
|
||||||
name = 'EPUB Output'
|
name = 'EPUB Output'
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
@ -92,51 +239,21 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
'as a blank page.')
|
'as a blank page.')
|
||||||
),
|
),
|
||||||
|
|
||||||
|
OptionRecommendation(name='preserve_cover_aspect_ratio',
|
||||||
|
recommended_value=False, help=_(
|
||||||
|
'When using an SVG cover, this option will cause the cover to scale '
|
||||||
|
'to cover the available screen area, but still preserve its aspect ratio '
|
||||||
|
'(ratio of width to height). That means there may be white borders '
|
||||||
|
'at the sides or top and bottom of the image, but the image will '
|
||||||
|
'never be distorted. Without this option the image may be slightly '
|
||||||
|
'distorted, but there will be no borders.'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
recommendations = set([('pretty_print', True, OptionRecommendation.HIGH)])
|
recommendations = set([('pretty_print', True, OptionRecommendation.HIGH)])
|
||||||
|
|
||||||
NONSVG_TITLEPAGE_COVER = '''\
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
<meta name="calibre:cover" content="true" />
|
|
||||||
<title>Cover</title>
|
|
||||||
<style type="text/css" title="override_css">
|
|
||||||
@page {padding: 0pt; margin:0pt}
|
|
||||||
body { text-align: center; padding:0pt; margin: 0pt; }
|
|
||||||
div { padding:0pt; margin: 0pt; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div>
|
|
||||||
<img src="%s" alt="cover" style="height: 100%%" />
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
'''
|
|
||||||
|
|
||||||
TITLEPAGE_COVER = '''\
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
<meta name="calibre:cover" content="true" />
|
|
||||||
<title>Cover</title>
|
|
||||||
<style type="text/css" title="override_css">
|
|
||||||
@page {padding: 0pt; margin:0pt}
|
|
||||||
body { text-align: center; padding:0pt; margin: 0pt; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
width="100%%" height="100%%" viewBox="0 0 600 800"
|
|
||||||
preserveAspectRatio="xMidYMid meet">
|
|
||||||
<image width="600" height="800" xlink:href="%s"/>
|
|
||||||
</svg>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
'''
|
|
||||||
|
|
||||||
def workaround_webkit_quirks(self):
|
def workaround_webkit_quirks(self):
|
||||||
from calibre.ebooks.oeb.base import XPath
|
from calibre.ebooks.oeb.base import XPath
|
||||||
@ -259,97 +376,6 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
ans += '\n</encryption>'
|
ans += '\n</encryption>'
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def default_cover(self):
|
|
||||||
'''
|
|
||||||
Create a generic cover for books that dont have a cover
|
|
||||||
'''
|
|
||||||
from calibre.utils.pil_draw import draw_centered_text
|
|
||||||
from calibre.ebooks.metadata import authors_to_string
|
|
||||||
if self.opts.no_default_epub_cover:
|
|
||||||
return None
|
|
||||||
self.log('Generating default cover')
|
|
||||||
m = self.oeb.metadata
|
|
||||||
title = unicode(m.title[0])
|
|
||||||
authors = [unicode(x) for x in m.creator if x.role == 'aut']
|
|
||||||
|
|
||||||
import cStringIO
|
|
||||||
cover_file = cStringIO.StringIO()
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
|
||||||
Image, ImageDraw, ImageFont
|
|
||||||
except ImportError:
|
|
||||||
import Image, ImageDraw, ImageFont
|
|
||||||
font_path = P('fonts/liberation/LiberationSerif-Bold.ttf')
|
|
||||||
app = '['+__appname__ +' '+__version__+']'
|
|
||||||
|
|
||||||
COVER_WIDTH, COVER_HEIGHT = 590, 750
|
|
||||||
img = Image.new('RGB', (COVER_WIDTH, COVER_HEIGHT), 'white')
|
|
||||||
draw = ImageDraw.Draw(img)
|
|
||||||
# Title
|
|
||||||
font = ImageFont.truetype(font_path, 44)
|
|
||||||
bottom = draw_centered_text(img, draw, font, title, 15, ysep=9)
|
|
||||||
# Authors
|
|
||||||
bottom += 14
|
|
||||||
font = ImageFont.truetype(font_path, 32)
|
|
||||||
authors = authors_to_string(authors)
|
|
||||||
bottom = draw_centered_text(img, draw, font, authors, bottom, ysep=7)
|
|
||||||
# Vanity
|
|
||||||
font = ImageFont.truetype(font_path, 28)
|
|
||||||
width, height = draw.textsize(app, font=font)
|
|
||||||
left = max(int((COVER_WIDTH - width)/2.), 0)
|
|
||||||
top = COVER_HEIGHT - height - 15
|
|
||||||
draw.text((left, top), app, fill=(0,0,0), font=font)
|
|
||||||
# Logo
|
|
||||||
logo = Image.open(I('library.png'), 'r')
|
|
||||||
width, height = logo.size
|
|
||||||
left = max(int((COVER_WIDTH - width)/2.), 0)
|
|
||||||
top = max(int((COVER_HEIGHT - height)/2.), 0)
|
|
||||||
img.paste(logo, (left, max(bottom, top)))
|
|
||||||
img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE)
|
|
||||||
|
|
||||||
img.convert('RGB').save(cover_file, 'JPEG')
|
|
||||||
cover_file.flush()
|
|
||||||
id, href = self.oeb.manifest.generate('cover_image', 'cover_image.jpg')
|
|
||||||
item = self.oeb.manifest.add(id, href, guess_type('t.jpg')[0],
|
|
||||||
data=cover_file.getvalue())
|
|
||||||
m.clear('cover')
|
|
||||||
m.add('cover', item.id)
|
|
||||||
|
|
||||||
return item.href
|
|
||||||
except:
|
|
||||||
self.log.exception('Failed to generate default cover')
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def insert_cover(self):
|
|
||||||
from calibre.ebooks.oeb.base import urldefrag
|
|
||||||
from calibre import guess_type
|
|
||||||
g, m = self.oeb.guide, self.oeb.manifest
|
|
||||||
item = None
|
|
||||||
if 'titlepage' not in g:
|
|
||||||
if 'cover' in g:
|
|
||||||
href = g['cover'].href
|
|
||||||
else:
|
|
||||||
href = self.default_cover()
|
|
||||||
if href is not None:
|
|
||||||
templ = self.NONSVG_TITLEPAGE_COVER if self.opts.no_svg_cover \
|
|
||||||
else self.TITLEPAGE_COVER
|
|
||||||
tp = templ%unquote(href)
|
|
||||||
id, href = m.generate('titlepage', 'titlepage.xhtml')
|
|
||||||
item = m.add(id, href, guess_type('t.xhtml')[0],
|
|
||||||
data=etree.fromstring(tp))
|
|
||||||
else:
|
|
||||||
item = self.oeb.manifest.hrefs[
|
|
||||||
urldefrag(self.oeb.guide['titlepage'].href)[0]]
|
|
||||||
if item is not None:
|
|
||||||
self.oeb.spine.insert(0, item, True)
|
|
||||||
if 'cover' not in self.oeb.guide.refs:
|
|
||||||
self.oeb.guide.add('cover', 'Title Page', 'a')
|
|
||||||
self.oeb.guide.refs['cover'].href = item.href
|
|
||||||
if 'titlepage' in self.oeb.guide.refs:
|
|
||||||
self.oeb.guide.refs['titlepage'].href = item.href
|
|
||||||
|
|
||||||
def condense_ncx(self, ncx_path):
|
def condense_ncx(self, ncx_path):
|
||||||
if not self.opts.pretty_print:
|
if not self.opts.pretty_print:
|
||||||
tree = etree.parse(ncx_path)
|
tree = etree.parse(ncx_path)
|
||||||
|
111
src/calibre/ebooks/metadata/book/__init__.py
Normal file
111
src/calibre/ebooks/metadata/book/__init__.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
'''
|
||||||
|
All fields must have a NULL value represented as None for simple types,
|
||||||
|
an empty list/dictionary for complex types and (None, None) for cover_data
|
||||||
|
'''
|
||||||
|
|
||||||
|
SOCIAL_METADATA_FIELDS = frozenset([
|
||||||
|
'tags', # Ordered list
|
||||||
|
# A floating point number between 0 and 10
|
||||||
|
'rating',
|
||||||
|
# A simple HTML enabled string
|
||||||
|
'comments',
|
||||||
|
# A simple string
|
||||||
|
'series',
|
||||||
|
# A floating point number
|
||||||
|
'series_index',
|
||||||
|
# Of the form { scheme1:value1, scheme2:value2}
|
||||||
|
# For example: {'isbn':'123456789', 'doi':'xxxx', ... }
|
||||||
|
'classifiers',
|
||||||
|
'isbn', # Pseudo field for convenience, should get/set isbn classifier
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
PUBLICATION_METADATA_FIELDS = frozenset([
|
||||||
|
# title must never be None. Should be _('Unknown')
|
||||||
|
'title',
|
||||||
|
# Pseudo field that can be set, but if not set is auto generated
|
||||||
|
# from title and languages
|
||||||
|
'title_sort',
|
||||||
|
# Ordered list of authors. Must never be None, can be [_('Unknown')]
|
||||||
|
'authors',
|
||||||
|
# Pseudo field that can be set, but if not set is auto generated
|
||||||
|
# from authors and languages
|
||||||
|
'author_sort',
|
||||||
|
'book_producer',
|
||||||
|
# Dates and times must be timezone aware
|
||||||
|
'timestamp',
|
||||||
|
'pubdate',
|
||||||
|
'rights',
|
||||||
|
# So far only known publication type is periodical:calibre
|
||||||
|
# If None, means book
|
||||||
|
'publication_type',
|
||||||
|
# A UUID usually of type 4
|
||||||
|
'uuid',
|
||||||
|
'languages', # ordered list
|
||||||
|
# Simple string, no special semantics
|
||||||
|
'publisher',
|
||||||
|
# Absolute path to image file encoded in filesystem_encoding
|
||||||
|
'cover',
|
||||||
|
# Of the form (format, data) where format is, for e.g. 'jpeg', 'png', 'gif'...
|
||||||
|
'cover_data',
|
||||||
|
# Either thumbnail data, or an object with the attribute
|
||||||
|
# image_path which is the path to an image file, encoded
|
||||||
|
# in filesystem_encoding
|
||||||
|
'thumbnail',
|
||||||
|
])
|
||||||
|
|
||||||
|
BOOK_STRUCTURE_FIELDS = frozenset([
|
||||||
|
# These are used by code, Null values are None.
|
||||||
|
'toc', 'spine', 'guide', 'manifest',
|
||||||
|
])
|
||||||
|
|
||||||
|
USER_METADATA_FIELDS = frozenset([
|
||||||
|
# A dict of a form to be specified
|
||||||
|
'user_metadata',
|
||||||
|
])
|
||||||
|
|
||||||
|
DEVICE_METADATA_FIELDS = frozenset([
|
||||||
|
# Ordered list of strings
|
||||||
|
'device_collections',
|
||||||
|
'lpath', # Unicode, / separated
|
||||||
|
# In bytes
|
||||||
|
'size',
|
||||||
|
# Mimetype of the book file being represented
|
||||||
|
'mime',
|
||||||
|
])
|
||||||
|
|
||||||
|
CALIBRE_METADATA_FIELDS = frozenset([
|
||||||
|
# An application id
|
||||||
|
# Semantics to be defined. Is it a db key? a db name + key? A uuid?
|
||||||
|
'application_id',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
RESERVED_METADATA_FIELDS = SOCIAL_METADATA_FIELDS.union(
|
||||||
|
PUBLICATION_METADATA_FIELDS).union(
|
||||||
|
BOOK_STRUCTURE_FIELDS).union(
|
||||||
|
USER_METADATA_FIELDS).union(
|
||||||
|
DEVICE_METADATA_FIELDS).union(
|
||||||
|
CALIBRE_METADATA_FIELDS)
|
||||||
|
|
||||||
|
assert len(RESERVED_METADATA_FIELDS) == sum(map(len, (
|
||||||
|
SOCIAL_METADATA_FIELDS, PUBLICATION_METADATA_FIELDS,
|
||||||
|
BOOK_STRUCTURE_FIELDS, USER_METADATA_FIELDS,
|
||||||
|
DEVICE_METADATA_FIELDS, CALIBRE_METADATA_FIELDS,
|
||||||
|
)))
|
||||||
|
|
||||||
|
SERIALIZABLE_FIELDS = SOCIAL_METADATA_FIELDS.union(
|
||||||
|
USER_METADATA_FIELDS).union(
|
||||||
|
PUBLICATION_METADATA_FIELDS).union(
|
||||||
|
CALIBRE_METADATA_FIELDS).union(
|
||||||
|
frozenset(['lpath'])) # I don't think we need device_collections
|
||||||
|
|
||||||
|
# Serialization of covers/thumbnails will have to be handled carefully, maybe
|
||||||
|
# as an option to the serializer class
|
129
src/calibre/ebooks/metadata/book/base.py
Normal file
129
src/calibre/ebooks/metadata/book/base.py
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
|
from calibre.ebooks.metadata.book import RESERVED_METADATA_FIELDS
|
||||||
|
|
||||||
|
NULL_VALUES = {
|
||||||
|
'user_metadata': {},
|
||||||
|
'cover_data' : (None, None),
|
||||||
|
'tags' : [],
|
||||||
|
'classifiers' : {},
|
||||||
|
'languages' : [],
|
||||||
|
'device_collections': [],
|
||||||
|
'authors' : [_('Unknown')],
|
||||||
|
'title' : _('Unknown'),
|
||||||
|
}
|
||||||
|
|
||||||
|
class Metadata(object):
|
||||||
|
|
||||||
|
'''
|
||||||
|
This class must expose a superset of the API of MetaInformation in terms
|
||||||
|
of attribute access and methods. Only the __init__ method is different.
|
||||||
|
MetaInformation will simply become a function that creates and fills in
|
||||||
|
the attributes of this class.
|
||||||
|
|
||||||
|
Please keep the method based API of this class to a minimum. Every method
|
||||||
|
becomes a reserved field name.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
object.__setattr__(self, '_data', copy.deepcopy(NULL_VALUES))
|
||||||
|
|
||||||
|
def __getattribute__(self, field):
|
||||||
|
_data = object.__getattribute__(self, '_data')
|
||||||
|
if field in RESERVED_METADATA_FIELDS:
|
||||||
|
return _data.get(field, None)
|
||||||
|
try:
|
||||||
|
return object.__getattribute__(self, field)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
if field in _data['user_metadata'].iterkeys():
|
||||||
|
# TODO: getting user metadata values
|
||||||
|
pass
|
||||||
|
raise AttributeError(
|
||||||
|
'Metadata object has no attribute named: '+ repr(field))
|
||||||
|
|
||||||
|
|
||||||
|
def __setattr__(self, field, val):
|
||||||
|
_data = object.__getattribute__(self, '_data')
|
||||||
|
if field in RESERVED_METADATA_FIELDS:
|
||||||
|
if field != 'user_metadata':
|
||||||
|
if not val:
|
||||||
|
val = NULL_VALUES[field]
|
||||||
|
_data[field] = val
|
||||||
|
else:
|
||||||
|
raise AttributeError('You cannot set user_metadata directly.')
|
||||||
|
elif field in _data['user_metadata'].iterkeys():
|
||||||
|
# TODO: Setting custom column values
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# You are allowed to stick arbitrary attributes onto this object as
|
||||||
|
# long as they dont conflict with global or user metadata names
|
||||||
|
# Don't abuse this privilege
|
||||||
|
self.__dict__[field] = val
|
||||||
|
|
||||||
|
@property
|
||||||
|
def reserved_names(self):
|
||||||
|
'The set of names you cannot use for your own purposes on this object'
|
||||||
|
_data = object.__getattribute__(self, '_data')
|
||||||
|
return frozenset(RESERVED_FIELD_NAMES).union(frozenset(
|
||||||
|
_data['user_metadata'].iterkeys()))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user_metadata_names(self):
|
||||||
|
'The set of user metadata names this object knows about'
|
||||||
|
_data = object.__getattribute__(self, '_data')
|
||||||
|
return frozenset(_data['user_metadata'].iterkeys())
|
||||||
|
|
||||||
|
# Old MetaInformation API {{{
|
||||||
|
def copy(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def print_all_attributes(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def smart_update(self, other):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def format_series_index(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def authors_from_string(self, raw):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def format_authors(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def format_tags(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def format_rating(self):
|
||||||
|
return unicode(self.rating)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def to_html(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.__unicode__().encode('utf-8')
|
||||||
|
|
||||||
|
def __nonzero__(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
_m = Metadata()
|
||||||
|
RESERVED_FIELD_NAMES = \
|
||||||
|
frozenset(_m.__dict__.iterkeys()).union( # _data
|
||||||
|
RESERVED_METADATA_FIELDS).union(
|
||||||
|
frozenset(Metadata.__dict__.iterkeys())) # methods defined in Metadata
|
||||||
|
del _m
|
||||||
|
|
@ -9,7 +9,6 @@ from threading import Thread
|
|||||||
from calibre import prints
|
from calibre import prints
|
||||||
from calibre.utils.config import OptionParser
|
from calibre.utils.config import OptionParser
|
||||||
from calibre.utils.logging import default_log
|
from calibre.utils.logging import default_log
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
|
||||||
from calibre.customize import Plugin
|
from calibre.customize import Plugin
|
||||||
|
|
||||||
metadata_config = None
|
metadata_config = None
|
||||||
@ -53,7 +52,7 @@ class MetadataSource(Plugin):
|
|||||||
if self.results:
|
if self.results:
|
||||||
c = self.config_store().get(self.name, {})
|
c = self.config_store().get(self.name, {})
|
||||||
res = self.results
|
res = self.results
|
||||||
if isinstance(res, MetaInformation):
|
if hasattr(res, 'authors'):
|
||||||
res = [res]
|
res = [res]
|
||||||
for mi in res:
|
for mi in res:
|
||||||
if not c.get('rating', True):
|
if not c.get('rating', True):
|
||||||
|
0
src/calibre/ebooks/metadata/odt.py
Executable file → Normal file
0
src/calibre/ebooks/metadata/odt.py
Executable file → Normal file
@ -669,10 +669,19 @@ class OPF(object):
|
|||||||
remove = list(self.authors_path(self.metadata))
|
remove = list(self.authors_path(self.metadata))
|
||||||
for elem in remove:
|
for elem in remove:
|
||||||
elem.getparent().remove(elem)
|
elem.getparent().remove(elem)
|
||||||
|
elems = []
|
||||||
for author in val:
|
for author in val:
|
||||||
attrib = {'{%s}role'%self.NAMESPACES['opf']: 'aut'}
|
attrib = {'{%s}role'%self.NAMESPACES['opf']: 'aut'}
|
||||||
elem = self.create_metadata_element('creator', attrib=attrib)
|
elem = self.create_metadata_element('creator', attrib=attrib)
|
||||||
self.set_text(elem, author.strip())
|
self.set_text(elem, author.strip())
|
||||||
|
# Ensure new author element is at the top of the list
|
||||||
|
# for broken implementations that always use the first
|
||||||
|
# <dc:creator> element with no attention to the role
|
||||||
|
elems.append(elem)
|
||||||
|
for elem in reversed(elems):
|
||||||
|
parent = elem.getparent()
|
||||||
|
parent.remove(elem)
|
||||||
|
parent.insert(0, elem)
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
|
@ -15,11 +15,39 @@ from calibre.customize.conversion import OutputFormatPlugin, \
|
|||||||
OptionRecommendation
|
OptionRecommendation
|
||||||
from calibre.ebooks.metadata.opf2 import OPF
|
from calibre.ebooks.metadata.opf2 import OPF
|
||||||
from calibre.ptempfile import TemporaryDirectory
|
from calibre.ptempfile import TemporaryDirectory
|
||||||
from calibre.ebooks.pdf.writer import PDFWriter, ImagePDFWriter, PDFMetadata
|
from calibre.ebooks.pdf.writer import PDFWriter, ImagePDFWriter, PDFMetadata, \
|
||||||
|
get_pdf_page_size
|
||||||
from calibre.ebooks.pdf.pageoptions import UNITS, PAPER_SIZES, \
|
from calibre.ebooks.pdf.pageoptions import UNITS, PAPER_SIZES, \
|
||||||
ORIENTATIONS
|
ORIENTATIONS
|
||||||
|
from calibre.ebooks.epub.output import CoverManager
|
||||||
|
|
||||||
class PDFOutput(OutputFormatPlugin):
|
class CoverManagerPDF(CoverManager):
|
||||||
|
|
||||||
|
def setup_cover(self, opts):
|
||||||
|
width, height = get_pdf_page_size(opts)
|
||||||
|
factor = opts.output_profile.dpi
|
||||||
|
self.NONSVG_TITLEPAGE_COVER = '''\
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<meta name="calibre:cover" content="true" />
|
||||||
|
<title>Cover</title>
|
||||||
|
<style type="text/css" title="override_css">
|
||||||
|
@page {padding: 0pt; margin:0pt}
|
||||||
|
body { text-align: center; padding:0pt; margin: 0pt; }
|
||||||
|
div { padding:0pt; margin: 0pt; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<img src="%%s" alt="cover" width="%d" height="%d" />
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
'''%(int(width*factor), int(height*factor)-5)
|
||||||
|
|
||||||
|
|
||||||
|
class PDFOutput(OutputFormatPlugin, CoverManagerPDF):
|
||||||
|
|
||||||
name = 'PDF Output'
|
name = 'PDF Output'
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -47,6 +75,7 @@ class PDFOutput(OutputFormatPlugin):
|
|||||||
])
|
])
|
||||||
|
|
||||||
def convert(self, oeb_book, output_path, input_plugin, opts, log):
|
def convert(self, oeb_book, output_path, input_plugin, opts, log):
|
||||||
|
self.oeb = oeb_book
|
||||||
self.input_plugin, self.opts, self.log = input_plugin, opts, log
|
self.input_plugin, self.opts, self.log = input_plugin, opts, log
|
||||||
self.output_path = output_path
|
self.output_path = output_path
|
||||||
self.metadata = oeb_book.metadata
|
self.metadata = oeb_book.metadata
|
||||||
@ -63,6 +92,10 @@ class PDFOutput(OutputFormatPlugin):
|
|||||||
|
|
||||||
def convert_text(self, oeb_book):
|
def convert_text(self, oeb_book):
|
||||||
self.log.debug('Serializing oeb input to disk for processing...')
|
self.log.debug('Serializing oeb input to disk for processing...')
|
||||||
|
self.opts.no_svg_cover = True
|
||||||
|
self.opts.no_default_epub_cover = True
|
||||||
|
self.setup_cover(self.opts)
|
||||||
|
self.insert_cover()
|
||||||
with TemporaryDirectory('_pdf_out') as oeb_dir:
|
with TemporaryDirectory('_pdf_out') as oeb_dir:
|
||||||
from calibre.customize.ui import plugin_for_output_format
|
from calibre.customize.ui import plugin_for_output_format
|
||||||
oeb_output = plugin_for_output_format('oeb')
|
oeb_output = plugin_for_output_format('oeb')
|
||||||
|
@ -18,11 +18,70 @@ from calibre.ebooks.metadata import authors_to_string
|
|||||||
|
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, \
|
from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, \
|
||||||
QPrinter, QMetaObject, QSizeF, Qt
|
QPrinter, QMetaObject, QSizeF, Qt, QPainter
|
||||||
from PyQt4.QtWebKit import QWebView
|
from PyQt4.QtWebKit import QWebView
|
||||||
|
|
||||||
from pyPdf import PdfFileWriter, PdfFileReader
|
from pyPdf import PdfFileWriter, PdfFileReader
|
||||||
|
|
||||||
|
def get_custom_size(opts):
|
||||||
|
custom_size = None
|
||||||
|
if opts.custom_size != None:
|
||||||
|
width, sep, height = opts.custom_size.partition('x')
|
||||||
|
if height != '':
|
||||||
|
try:
|
||||||
|
width = int(width)
|
||||||
|
height = int(height)
|
||||||
|
custom_size = (width, height)
|
||||||
|
except:
|
||||||
|
custom_size = None
|
||||||
|
return custom_size
|
||||||
|
|
||||||
|
def get_pdf_page_size(opts):
|
||||||
|
from calibre.gui2 import is_ok_to_use_qt
|
||||||
|
if not is_ok_to_use_qt():
|
||||||
|
raise Exception('Not OK to use Qt')
|
||||||
|
|
||||||
|
printer = QPrinter(QPrinter.HighResolution)
|
||||||
|
custom_size = get_custom_size(opts)
|
||||||
|
|
||||||
|
if opts.output_profile.short_name == 'default':
|
||||||
|
if custom_size is None:
|
||||||
|
printer.setPaperSize(paper_size(opts.paper_size))
|
||||||
|
else:
|
||||||
|
printer.setPaperSize(QSizeF(custom_size[0], custom_size[1]), unit(opts.unit))
|
||||||
|
else:
|
||||||
|
printer.setPaperSize(QSizeF(opts.output_profile.width / opts.output_profile.dpi,
|
||||||
|
opts.output_profile.height / opts.output_profile.dpi), QPrinter.Inch)
|
||||||
|
|
||||||
|
printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
|
||||||
|
printer.setOrientation(orientation(opts.orientation))
|
||||||
|
printer.setOutputFormat(QPrinter.PdfFormat)
|
||||||
|
|
||||||
|
size = printer.paperSize(QPrinter.Millimeter)
|
||||||
|
|
||||||
|
return size.width() / 10, size.height() / 10
|
||||||
|
|
||||||
|
def get_imagepdf_page_size(opts):
|
||||||
|
printer = QPrinter(QPrinter.HighResolution)
|
||||||
|
custom_size = get_custom_size(opts)
|
||||||
|
|
||||||
|
if opts.output_profile.short_name == 'default':
|
||||||
|
if custom_size == None:
|
||||||
|
printer.setPaperSize(paper_size(opts.paper_size))
|
||||||
|
else:
|
||||||
|
printer.setPaperSize(QSizeF(custom_size[0], custom_size[1]), unit(opts.unit))
|
||||||
|
else:
|
||||||
|
printer.setPaperSize(QSizeF(opts.output_profile.comic_screen_size[0] / opts.output_profile.dpi,
|
||||||
|
opts.output_profile.comic_screen_size[1] / opts.output_profile.dpi), QPrinter.Inch)
|
||||||
|
|
||||||
|
printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
|
||||||
|
printer.setOrientation(orientation(opts.orientation))
|
||||||
|
printer.setOutputFormat(QPrinter.PdfFormat)
|
||||||
|
|
||||||
|
size = printer.paperSize(QPrinter.Millimeter)
|
||||||
|
|
||||||
|
return size.width() / 10, size.height() / 10
|
||||||
|
|
||||||
class PDFMetadata(object):
|
class PDFMetadata(object):
|
||||||
def __init__(self, oeb_metadata=None):
|
def __init__(self, oeb_metadata=None):
|
||||||
self.title = _('Unknown')
|
self.title = _('Unknown')
|
||||||
@ -36,6 +95,7 @@ class PDFMetadata(object):
|
|||||||
|
|
||||||
|
|
||||||
class PDFWriter(QObject):
|
class PDFWriter(QObject):
|
||||||
|
|
||||||
def __init__(self, opts, log):
|
def __init__(self, opts, log):
|
||||||
from calibre.gui2 import is_ok_to_use_qt
|
from calibre.gui2 import is_ok_to_use_qt
|
||||||
if not is_ok_to_use_qt():
|
if not is_ok_to_use_qt():
|
||||||
@ -46,25 +106,15 @@ class PDFWriter(QObject):
|
|||||||
|
|
||||||
self.loop = QEventLoop()
|
self.loop = QEventLoop()
|
||||||
self.view = QWebView()
|
self.view = QWebView()
|
||||||
|
self.view.setRenderHints(QPainter.Antialiasing|QPainter.TextAntialiasing|QPainter.SmoothPixmapTransform)
|
||||||
self.connect(self.view, SIGNAL('loadFinished(bool)'), self._render_html)
|
self.connect(self.view, SIGNAL('loadFinished(bool)'), self._render_html)
|
||||||
self.render_queue = []
|
self.render_queue = []
|
||||||
self.combine_queue = []
|
self.combine_queue = []
|
||||||
self.tmp_path = PersistentTemporaryDirectory('_pdf_output_parts')
|
self.tmp_path = PersistentTemporaryDirectory('_pdf_output_parts')
|
||||||
|
|
||||||
self.custom_size = None
|
|
||||||
if opts.custom_size != None:
|
|
||||||
width, sep, height = opts.custom_size.partition('x')
|
|
||||||
if height != '':
|
|
||||||
try:
|
|
||||||
width = int(width)
|
|
||||||
height = int(height)
|
|
||||||
self.custom_size = (width, height)
|
|
||||||
except:
|
|
||||||
self.custom_size = None
|
|
||||||
|
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
|
|
||||||
self.size = self._size()
|
self.size = get_pdf_page_size(opts)
|
||||||
|
|
||||||
def dump(self, items, out_stream, pdf_metadata):
|
def dump(self, items, out_stream, pdf_metadata):
|
||||||
self.metadata = pdf_metadata
|
self.metadata = pdf_metadata
|
||||||
@ -77,27 +127,6 @@ class PDFWriter(QObject):
|
|||||||
QMetaObject.invokeMethod(self, "_render_book", Qt.QueuedConnection)
|
QMetaObject.invokeMethod(self, "_render_book", Qt.QueuedConnection)
|
||||||
self.loop.exec_()
|
self.loop.exec_()
|
||||||
|
|
||||||
def _size(self):
|
|
||||||
'''
|
|
||||||
The size of a pdf page in cm.
|
|
||||||
'''
|
|
||||||
printer = QPrinter(QPrinter.HighResolution)
|
|
||||||
|
|
||||||
if self.opts.output_profile.short_name == 'default':
|
|
||||||
if self.custom_size == None:
|
|
||||||
printer.setPaperSize(paper_size(self.opts.paper_size))
|
|
||||||
else:
|
|
||||||
printer.setPaperSize(QSizeF(self.custom_size[0], self.custom_size[1]), unit(self.opts.unit))
|
|
||||||
else:
|
|
||||||
printer.setPaperSize(QSizeF(self.opts.output_profile.width / self.opts.output_profile.dpi, self.opts.output_profile.height / self.opts.output_profile.dpi), QPrinter.Inch)
|
|
||||||
|
|
||||||
printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
|
|
||||||
printer.setOrientation(orientation(self.opts.orientation))
|
|
||||||
printer.setOutputFormat(QPrinter.PdfFormat)
|
|
||||||
|
|
||||||
size = printer.paperSize(QPrinter.Millimeter)
|
|
||||||
|
|
||||||
return size.width() / 10, size.height() / 10
|
|
||||||
|
|
||||||
@QtCore.pyqtSignature('_render_book()')
|
@QtCore.pyqtSignature('_render_book()')
|
||||||
def _render_book(self):
|
def _render_book(self):
|
||||||
@ -151,6 +180,10 @@ class PDFWriter(QObject):
|
|||||||
|
|
||||||
class ImagePDFWriter(PDFWriter):
|
class ImagePDFWriter(PDFWriter):
|
||||||
|
|
||||||
|
def __init__(self, opts, log):
|
||||||
|
PDFWriter.__init__(self, opts, log)
|
||||||
|
self.size = get_imagepdf_page_size(opts)
|
||||||
|
|
||||||
def _render_next(self):
|
def _render_next(self):
|
||||||
item = str(self.render_queue.pop(0))
|
item = str(self.render_queue.pop(0))
|
||||||
self.combine_queue.append(os.path.join(self.tmp_path, '%i.pdf' % (len(self.combine_queue) + 1)))
|
self.combine_queue.append(os.path.join(self.tmp_path, '%i.pdf' % (len(self.combine_queue) + 1)))
|
||||||
@ -163,22 +196,4 @@ class ImagePDFWriter(PDFWriter):
|
|||||||
|
|
||||||
self.view.setHtml(html)
|
self.view.setHtml(html)
|
||||||
|
|
||||||
def _size(self):
|
|
||||||
printer = QPrinter(QPrinter.HighResolution)
|
|
||||||
|
|
||||||
if self.opts.output_profile.short_name == 'default':
|
|
||||||
if self.custom_size == None:
|
|
||||||
printer.setPaperSize(paper_size(self.opts.paper_size))
|
|
||||||
else:
|
|
||||||
printer.setPaperSize(QSizeF(self.custom_size[0], self.custom_size[1]), unit(self.opts.unit))
|
|
||||||
else:
|
|
||||||
printer.setPaperSize(QSizeF(self.opts.output_profile.comic_screen_size[0] / self.opts.output_profile.dpi, self.opts.output_profile.comic_screen_size[1] / self.opts.output_profile.dpi), QPrinter.Inch)
|
|
||||||
|
|
||||||
printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
|
|
||||||
printer.setOrientation(orientation(self.opts.orientation))
|
|
||||||
printer.setOutputFormat(QPrinter.PdfFormat)
|
|
||||||
|
|
||||||
size = printer.paperSize(QPrinter.Millimeter)
|
|
||||||
|
|
||||||
return size.width() / 10, size.height() / 10
|
|
||||||
|
|
||||||
|
@ -18,8 +18,11 @@ class PluginWidget(Widget, Ui_Form):
|
|||||||
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
||||||
Widget.__init__(self, parent, 'epub_output',
|
Widget.__init__(self, parent, 'epub_output',
|
||||||
['dont_split_on_page_breaks', 'flow_size',
|
['dont_split_on_page_breaks', 'flow_size',
|
||||||
'no_default_epub_cover', 'no_svg_cover']
|
'no_default_epub_cover', 'no_svg_cover',
|
||||||
|
'preserve_cover_aspect_ratio',]
|
||||||
)
|
)
|
||||||
|
for i in range(2):
|
||||||
|
self.opt_no_svg_cover.toggle()
|
||||||
self.db, self.book_id = db, book_id
|
self.db, self.book_id = db, book_id
|
||||||
self.initialize_options(get_option, get_help, db, book_id)
|
self.initialize_options(get_option, get_help, db, book_id)
|
||||||
|
|
||||||
|
@ -14,13 +14,34 @@
|
|||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0">
|
||||||
<widget class="QCheckBox" name="opt_dont_split_on_page_breaks">
|
<widget class="QCheckBox" name="opt_dont_split_on_page_breaks">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Do not &split on page breaks</string>
|
<string>Do not &split on page breaks</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_no_default_epub_cover">
|
||||||
|
<property name="text">
|
||||||
|
<string>No default &cover</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_no_svg_cover">
|
||||||
|
<property name="text">
|
||||||
|
<string>No &SVG cover</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QCheckBox" name="opt_preserve_cover_aspect_ratio">
|
||||||
|
<property name="text">
|
||||||
|
<string>Preserve cover &aspect ratio</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -60,22 +81,25 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="opt_no_default_epub_cover">
|
|
||||||
<property name="text">
|
|
||||||
<string>No default &cover</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QCheckBox" name="opt_no_svg_cover">
|
|
||||||
<property name="text">
|
|
||||||
<string>No &SVG cover</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>opt_no_svg_cover</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>opt_preserve_cover_aspect_ratio</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>81</x>
|
||||||
|
<y>73</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>237</x>
|
||||||
|
<y>68</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -8,9 +8,9 @@ from functools import partial
|
|||||||
from PyQt4.QtCore import SIGNAL
|
from PyQt4.QtCore import SIGNAL
|
||||||
from PyQt4.Qt import QDialog, Qt, QListWidgetItem, QVariant
|
from PyQt4.Qt import QDialog, Qt, QListWidgetItem, QVariant
|
||||||
|
|
||||||
from calibre.devices.metadata_serializer import metadata_serializer
|
|
||||||
from calibre.gui2.dialogs.config.create_custom_column_ui import Ui_QCreateCustomColumn
|
from calibre.gui2.dialogs.config.create_custom_column_ui import Ui_QCreateCustomColumn
|
||||||
from calibre.gui2 import error_dialog
|
from calibre.gui2 import error_dialog
|
||||||
|
from calibre.ebooks.metadata.book.base import RESERVED_FIELD_NAMES
|
||||||
|
|
||||||
class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
|
class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
|
|||||||
return self.simple_error('', _('No lookup name was provided'))
|
return self.simple_error('', _('No lookup name was provided'))
|
||||||
if not col_heading:
|
if not col_heading:
|
||||||
return self.simple_error('', _('No column heading was provided'))
|
return self.simple_error('', _('No column heading was provided'))
|
||||||
if col in metadata_serializer.SERIALIZED_ATTRS:
|
if col in RESERVED_FIELD_NAMES:
|
||||||
return self.simple_error('', _('The lookup name %s is reserved and cannot be used')%col)
|
return self.simple_error('', _('The lookup name %s is reserved and cannot be used')%col)
|
||||||
bad_col = False
|
bad_col = False
|
||||||
if col in self.parent.custcols:
|
if col in self.parent.custcols:
|
||||||
|
@ -135,7 +135,6 @@ class SearchBox2(QComboBox):
|
|||||||
|
|
||||||
def text_edited_slot(self, text):
|
def text_edited_slot(self, text):
|
||||||
if self.as_you_type:
|
if self.as_you_type:
|
||||||
text = unicode(text)
|
|
||||||
self.timer = self.startTimer(self.__class__.INTERVAL)
|
self.timer = self.startTimer(self.__class__.INTERVAL)
|
||||||
|
|
||||||
def timerEvent(self, event):
|
def timerEvent(self, event):
|
||||||
|
@ -145,7 +145,7 @@ First perform the following steps in |app|
|
|||||||
|
|
||||||
For an iPad:
|
For an iPad:
|
||||||
|
|
||||||
Install the ReadMe app on your iPad using iTunes. Open Safari and browse to::
|
Install the ReadMe app on your iPad using iTunes. Open the Readme builtin browser and browse to::
|
||||||
|
|
||||||
http://192.168.1.2:8080/
|
http://192.168.1.2:8080/
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: calibre 0.6.53\n"
|
"Project-Id-Version: calibre 0.6.54\n"
|
||||||
"POT-Creation-Date: 2010-05-15 21:26+MDT\n"
|
"POT-Creation-Date: 2010-05-21 15:44+MDT\n"
|
||||||
"PO-Revision-Date: 2010-05-15 21:26+MDT\n"
|
"PO-Revision-Date: 2010-05-21 15:44+MDT\n"
|
||||||
"Last-Translator: Automatically generated\n"
|
"Last-Translator: Automatically generated\n"
|
||||||
"Language-Team: LANGUAGE\n"
|
"Language-Team: LANGUAGE\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -95,8 +95,8 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/rotate.py:63
|
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/rotate.py:63
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:81
|
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:81
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:82
|
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:82
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:28
|
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:87
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:29
|
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:88
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:233
|
#: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:233
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:235
|
#: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:235
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:279
|
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:279
|
||||||
@ -135,7 +135,7 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:671
|
#: /home/kovid/work/calibre/src/calibre/library/server.py:671
|
||||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:747
|
#: /home/kovid/work/calibre/src/calibre/library/server.py:747
|
||||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:794
|
#: /home/kovid/work/calibre/src/calibre/library/server.py:794
|
||||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:113
|
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:114
|
||||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:45
|
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:45
|
||||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:63
|
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:63
|
||||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:77
|
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:77
|
||||||
@ -247,7 +247,7 @@ msgid "This profile tries to provide sane defaults and is useful if you know not
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:57
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:57
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:256
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:258
|
||||||
msgid "This profile is intended for the SONY PRS line. The 500/505/600/700 etc."
|
msgid "This profile is intended for the SONY PRS line. The 500/505/600/700 etc."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -256,62 +256,62 @@ msgid "This profile is intended for the SONY PRS 300."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:78
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:78
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:290
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:292
|
||||||
msgid "This profile is intended for the SONY PRS-900."
|
msgid "This profile is intended for the SONY PRS-900."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:86
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:86
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:320
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:322
|
||||||
msgid "This profile is intended for the Microsoft Reader."
|
msgid "This profile is intended for the Microsoft Reader."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:97
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:97
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:331
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:333
|
||||||
msgid "This profile is intended for the Mobipocket books."
|
msgid "This profile is intended for the Mobipocket books."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:110
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:110
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:344
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:346
|
||||||
msgid "This profile is intended for the Hanlin V3 and its clones."
|
msgid "This profile is intended for the Hanlin V3 and its clones."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:122
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:122
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:356
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:358
|
||||||
msgid "This profile is intended for the Hanlin V5 and its clones."
|
msgid "This profile is intended for the Hanlin V5 and its clones."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:132
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:132
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:364
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:366
|
||||||
msgid "This profile is intended for the Cybook G3."
|
msgid "This profile is intended for the Cybook G3."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:145
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:145
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:377
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:379
|
||||||
msgid "This profile is intended for the Cybook Opus."
|
msgid "This profile is intended for the Cybook Opus."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:157
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:157
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:388
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:390
|
||||||
msgid "This profile is intended for the Amazon Kindle."
|
msgid "This profile is intended for the Amazon Kindle."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:169
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:169
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:423
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:425
|
||||||
msgid "This profile is intended for the Irex Illiad."
|
msgid "This profile is intended for the Irex Illiad."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:181
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:181
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:436
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:438
|
||||||
msgid "This profile is intended for the IRex Digital Reader 1000."
|
msgid "This profile is intended for the IRex Digital Reader 1000."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:194
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:194
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:450
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:452
|
||||||
msgid "This profile is intended for the IRex Digital Reader 800."
|
msgid "This profile is intended for the IRex Digital Reader 800."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:206
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:206
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:464
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:466
|
||||||
msgid "This profile is intended for the B&N Nook."
|
msgid "This profile is intended for the B&N Nook."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -323,23 +323,27 @@ msgstr ""
|
|||||||
msgid "This profile tries to provide sane defaults and is useful if you want to produce a document intended to be read at a computer or on a range of devices."
|
msgid "This profile tries to provide sane defaults and is useful if you want to produce a document intended to be read at a computer or on a range of devices."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:269
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:248
|
||||||
|
msgid "Intended for the iPad and similar devices with a resolution of 768x1024"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:271
|
||||||
msgid "This profile is intended for the Kobo Reader."
|
msgid "This profile is intended for the Kobo Reader."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:281
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:283
|
||||||
msgid "This profile is intended for the SONY PRS-300."
|
msgid "This profile is intended for the SONY PRS-300."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:299
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:301
|
||||||
msgid "This profile is intended for the 5-inch JetBook."
|
msgid "This profile is intended for the 5-inch JetBook."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:308
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:310
|
||||||
msgid "This profile is intended for the SONY PRS line. The 500/505/700 etc, in landscape mode. Mainly useful for comics."
|
msgid "This profile is intended for the SONY PRS line. The 500/505/700 etc, in landscape mode. Mainly useful for comics."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:406
|
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:408
|
||||||
msgid "This profile is intended for the Amazon Kindle DX."
|
msgid "This profile is intended for the Amazon Kindle DX."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -403,11 +407,11 @@ msgstr ""
|
|||||||
msgid "Communicate with Android phones."
|
msgid "Communicate with Android phones."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/android/driver.py:36
|
#: /home/kovid/work/calibre/src/calibre/devices/android/driver.py:39
|
||||||
msgid "Comma separated list of directories to send e-books to on the device. The first one that exists will be used"
|
msgid "Comma separated list of directories to send e-books to on the device. The first one that exists will be used"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/android/driver.py:64
|
#: /home/kovid/work/calibre/src/calibre/devices/android/driver.py:67
|
||||||
msgid "Communicate with S60 phones."
|
msgid "Communicate with S60 phones."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -523,7 +527,7 @@ msgstr ""
|
|||||||
msgid "Communicate with the Kobo Reader"
|
msgid "Communicate with the Kobo Reader"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/misc.py:55
|
#: /home/kovid/work/calibre/src/calibre/devices/misc.py:56
|
||||||
msgid "Communicate with the Booq Avant"
|
msgid "Communicate with the Booq Avant"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -604,6 +608,14 @@ msgstr ""
|
|||||||
msgid "Communicate with the Teclast K3 reader."
|
msgid "Communicate with the Teclast K3 reader."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/devices/teclast/driver.py:45
|
||||||
|
msgid "Communicate with the Newsmy reader."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/devices/teclast/driver.py:60
|
||||||
|
msgid "Communicate with the iPapyrus reader."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:252
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:252
|
||||||
msgid "Unable to detect the %s disk drive. Try rebooting."
|
msgid "Unable to detect the %s disk drive. Try rebooting."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -916,280 +928,288 @@ msgstr ""
|
|||||||
msgid "Output saved to"
|
msgid "Output saved to"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:94
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:95
|
||||||
msgid "Level of verbosity. Specify multiple times for greater verbosity."
|
msgid "Level of verbosity. Specify multiple times for greater verbosity."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:101
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:102
|
||||||
msgid "Save the output from different stages of the conversion pipeline to the specified directory. Useful if you are unsure at which stage of the conversion process a bug is occurring."
|
msgid "Save the output from different stages of the conversion pipeline to the specified directory. Useful if you are unsure at which stage of the conversion process a bug is occurring."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:110
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:111
|
||||||
msgid "Specify the input profile. The input profile gives the conversion system information on how to interpret various information in the input document. For example resolution dependent lengths (i.e. lengths in pixels). Choices are:"
|
msgid "Specify the input profile. The input profile gives the conversion system information on how to interpret various information in the input document. For example resolution dependent lengths (i.e. lengths in pixels). Choices are:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:121
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:122
|
||||||
msgid "Specify the output profile. The output profile tells the conversion system how to optimize the created document for the specified device. In some cases, an output profile is required to produce documents that will work on a device. For example EPUB on the SONY reader. Choices are:"
|
msgid "Specify the output profile. The output profile tells the conversion system how to optimize the created document for the specified device. In some cases, an output profile is required to produce documents that will work on a device. For example EPUB on the SONY reader. Choices are:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:132
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:133
|
||||||
msgid "The base font size in pts. All font sizes in the produced book will be rescaled based on this size. By choosing a larger size you can make the fonts in the output bigger and vice versa. By default, the base font size is chosen based on the output profile you chose."
|
msgid "The base font size in pts. All font sizes in the produced book will be rescaled based on this size. By choosing a larger size you can make the fonts in the output bigger and vice versa. By default, the base font size is chosen based on the output profile you chose."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:142
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:143
|
||||||
msgid "Mapping from CSS font names to font sizes in pts. An example setting is 12,12,14,16,18,20,22,24. These are the mappings for the sizes xx-small to xx-large, with the final size being for huge fonts. The font rescaling algorithm uses these sizes to intelligently rescale fonts. The default is to use a mapping based on the output profile you chose."
|
msgid "Mapping from CSS font names to font sizes in pts. An example setting is 12,12,14,16,18,20,22,24. These are the mappings for the sizes xx-small to xx-large, with the final size being for huge fonts. The font rescaling algorithm uses these sizes to intelligently rescale fonts. The default is to use a mapping based on the output profile you chose."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:154
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:155
|
||||||
msgid "Disable all rescaling of font sizes."
|
msgid "Disable all rescaling of font sizes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:161
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:162
|
||||||
msgid "The line height in pts. Controls spacing between consecutive lines of text. By default no line height manipulation is performed."
|
msgid "The line height in pts. Controls spacing between consecutive lines of text. By default no line height manipulation is performed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:169
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:170
|
||||||
msgid "Some badly designed documents use tables to control the layout of text on the page. When converted these documents often have text that runs off the page and other artifacts. This option will extract the content from the tables and present it in a linear fashion."
|
msgid "Some badly designed documents use tables to control the layout of text on the page. When converted these documents often have text that runs off the page and other artifacts. This option will extract the content from the tables and present it in a linear fashion."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:179
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:180
|
||||||
msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level one. If this is specified, it takes precedence over other forms of auto-detection."
|
msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level one. If this is specified, it takes precedence over other forms of auto-detection."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:188
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:189
|
||||||
msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level two. Each entry is added under the previous level one entry."
|
msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level two. Each entry is added under the previous level one entry."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:196
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:197
|
||||||
msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level three. Each entry is added under the previous level two entry."
|
msgid "XPath expression that specifies all tags that should be added to the Table of Contents at level three. Each entry is added under the previous level two entry."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:204
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:205
|
||||||
msgid "Normally, if the source file already has a Table of Contents, it is used in preference to the auto-generated one. With this option, the auto-generated one is always used."
|
msgid "Normally, if the source file already has a Table of Contents, it is used in preference to the auto-generated one. With this option, the auto-generated one is always used."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:212
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:213
|
||||||
msgid "Don't add auto-detected chapters to the Table of Contents."
|
msgid "Don't add auto-detected chapters to the Table of Contents."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:219
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:220
|
||||||
msgid "If fewer than this number of chapters is detected, then links are added to the Table of Contents. Default: %default"
|
msgid "If fewer than this number of chapters is detected, then links are added to the Table of Contents. Default: %default"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:226
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:227
|
||||||
msgid "Maximum number of links to insert into the TOC. Set to 0 to disable. Default is: %default. Links are only added to the TOC if less than the threshold number of chapters were detected."
|
msgid "Maximum number of links to insert into the TOC. Set to 0 to disable. Default is: %default. Links are only added to the TOC if less than the threshold number of chapters were detected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:234
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:235
|
||||||
msgid "Remove entries from the Table of Contents whose titles match the specified regular expression. Matching entries and all their children are removed."
|
msgid "Remove entries from the Table of Contents whose titles match the specified regular expression. Matching entries and all their children are removed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:245
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:246
|
||||||
msgid "An XPath expression to detect chapter titles. The default is to consider <h1> or <h2> tags that contain the words \"chapter\",\"book\",\"section\" or \"part\" as chapter titles as well as any tags that have class=\"chapter\". The expression used must evaluate to a list of elements. To disable chapter detection, use the expression \"/\". See the XPath Tutorial in the calibre User Manual for further help on using this feature."
|
msgid "An XPath expression to detect chapter titles. The default is to consider <h1> or <h2> tags that contain the words \"chapter\",\"book\",\"section\" or \"part\" as chapter titles as well as any tags that have class=\"chapter\". The expression used must evaluate to a list of elements. To disable chapter detection, use the expression \"/\". See the XPath Tutorial in the calibre User Manual for further help on using this feature."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:259
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:260
|
||||||
msgid "Specify how to mark detected chapters. A value of \"pagebreak\" will insert page breaks before chapters. A value of \"rule\" will insert a line before chapters. A value of \"none\" will disable chapter marking and a value of \"both\" will use both page breaks and lines to mark chapters."
|
msgid "Specify how to mark detected chapters. A value of \"pagebreak\" will insert page breaks before chapters. A value of \"rule\" will insert a line before chapters. A value of \"none\" will disable chapter marking and a value of \"both\" will use both page breaks and lines to mark chapters."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:269
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:270
|
||||||
msgid "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."
|
msgid "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."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:278
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:279
|
||||||
msgid "An XPath expression. Page breaks are inserted before the specified elements."
|
msgid "An XPath expression. Page breaks are inserted before the specified elements."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:284
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:285
|
||||||
msgid "Set the top margin in pts. Default is %default. Note: 72 pts equals 1 inch"
|
msgid "Set the top margin in pts. Default is %default. Note: 72 pts equals 1 inch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:289
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:290
|
||||||
msgid "Set the bottom margin in pts. Default is %default. Note: 72 pts equals 1 inch"
|
msgid "Set the bottom margin in pts. Default is %default. Note: 72 pts equals 1 inch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:294
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:295
|
||||||
msgid "Set the left margin in pts. Default is %default. Note: 72 pts equals 1 inch"
|
msgid "Set the left margin in pts. Default is %default. Note: 72 pts equals 1 inch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:299
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:300
|
||||||
msgid "Set the right margin in pts. Default is %default. Note: 72 pts equals 1 inch"
|
msgid "Set the right margin in pts. Default is %default. Note: 72 pts equals 1 inch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:305
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:306
|
||||||
msgid "Change text justification. A value of \"left\" converts all justified text in the source to left aligned (i.e. unjustified) text. A value of \"justify\" converts all unjustified text to justified. A value of \"original\" (the default) does not change justification in the source file. Note that only some output formats support justification."
|
msgid "Change text justification. A value of \"left\" converts all justified text in the source to left aligned (i.e. unjustified) text. A value of \"justify\" converts all unjustified text to justified. A value of \"original\" (the default) does not change justification in the source file. Note that only some output formats support justification."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:315
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:316
|
||||||
msgid "Remove spacing between paragraphs. Also sets an indent on paragraphs of 1.5em. Spacing removal will not work if the source file does not use paragraphs (<p> or <div> tags)."
|
msgid "Remove spacing between paragraphs. Also sets an indent on paragraphs of 1.5em. Spacing removal will not work if the source file does not use paragraphs (<p> or <div> tags)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:322
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:323
|
||||||
msgid "When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent."
|
msgid "When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:329
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:330
|
||||||
msgid "Use the cover detected from the source file in preference to the specified cover."
|
msgid "Use the cover detected from the source file in preference to the specified cover."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:335
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:336
|
||||||
msgid "Insert a blank line between paragraphs. Will not work if the source file does not use paragraphs (<p> or <div> tags)."
|
msgid "Insert a blank line between paragraphs. Will not work if the source file does not use paragraphs (<p> or <div> tags)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:342
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:343
|
||||||
msgid "Remove the first image from the input ebook. Useful if the first image in the source file is a cover and you are specifying an external cover."
|
msgid "Remove the first image from the input ebook. Useful if the first image in the source file is a cover and you are specifying an external cover."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:350
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:351
|
||||||
msgid "Insert the book metadata at the start of the book. This is useful if your ebook reader does not support displaying/searching metadata directly."
|
msgid "Insert the book metadata at the start of the book. This is useful if your ebook reader does not support displaying/searching metadata directly."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:358
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:359
|
||||||
msgid "Attempt to detect and correct hard line breaks and other problems in the source file. This may make things worse, so use with care."
|
msgid "Attempt to detect and correct hard line breaks and other problems in the source file. This may make things worse, so use with care."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:366
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:367
|
||||||
msgid "Use a regular expression to try and remove the header."
|
msgid "Use a regular expression to try and remove the header."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:373
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:374
|
||||||
msgid "The regular expression to use to remove the header."
|
msgid "The regular expression to use to remove the header."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:379
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:380
|
||||||
msgid "Use a regular expression to try and remove the footer."
|
msgid "Use a regular expression to try and remove the footer."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:386
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:387
|
||||||
msgid "The regular expression to use to remove the footer."
|
msgid "The regular expression to use to remove the footer."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:393
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:394
|
||||||
msgid "Read metadata from the specified OPF file. Metadata read from this file will override any metadata in the source file."
|
msgid "Read metadata from the specified OPF file. Metadata read from this file will override any metadata in the source file."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:400
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:401
|
||||||
msgid "Transliterate unicode characters to an ASCII representation. Use with care because this will replace unicode characters with ASCII. For instance it will replace \"%s\" with \"Mikhail Gorbachiov\". Also, note that in cases where there are multiple representations of a character (characters shared by Chinese and Japanese for instance) the representation used by the largest number of people will be used (Chinese in the previous example)."
|
msgid "Transliterate unicode characters to an ASCII representation. Use with care because this will replace unicode characters with ASCII. For instance it will replace \"%s\" with \"Mikhail Gorbachiov\". Also, note that in cases where there are multiple representations of a character (characters shared by Chinese and Japanese for instance) the representation used by the largest number of people will be used (Chinese in the previous example)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:415
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:416
|
||||||
|
msgid "Preserve ligatures present in the input document. A ligature is a special rendering of a pair of characters like ff, fi, fl et cetera. Most readers do not have support for ligatures in their default fonts, so they are unlikely to render correctly. By default, calibre will turn a ligature into the corresponding pair of normal characters. This option will preserve them instead."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:428
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:38
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:38
|
||||||
msgid "Set the title."
|
msgid "Set the title."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:419
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:432
|
||||||
msgid "Set the authors. Multiple authors should be separated by ampersands."
|
msgid "Set the authors. Multiple authors should be separated by ampersands."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:424
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:437
|
||||||
msgid "The version of the title to be used for sorting. "
|
msgid "The version of the title to be used for sorting. "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:428
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:441
|
||||||
msgid "String to be used when sorting by author. "
|
msgid "String to be used when sorting by author. "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:432
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:445
|
||||||
msgid "Set the cover to the specified file or URL"
|
msgid "Set the cover to the specified file or URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:436
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:449
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:54
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:54
|
||||||
msgid "Set the ebook description."
|
msgid "Set the ebook description."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:440
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:453
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:56
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:56
|
||||||
msgid "Set the ebook publisher."
|
msgid "Set the ebook publisher."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:444
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:457
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:60
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:60
|
||||||
msgid "Set the series this ebook belongs to."
|
msgid "Set the series this ebook belongs to."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:448
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:461
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:62
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:62
|
||||||
msgid "Set the index of the book in this series."
|
msgid "Set the index of the book in this series."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:452
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:465
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:64
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:64
|
||||||
msgid "Set the rating. Should be a number between 1 and 5."
|
msgid "Set the rating. Should be a number between 1 and 5."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:456
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:469
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:66
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:66
|
||||||
msgid "Set the ISBN of the book."
|
msgid "Set the ISBN of the book."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:460
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:473
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:68
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:68
|
||||||
msgid "Set the tags for the book. Should be a comma separated list."
|
msgid "Set the tags for the book. Should be a comma separated list."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:464
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:477
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:70
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:70
|
||||||
msgid "Set the book producer."
|
msgid "Set the book producer."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:468
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:481
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:72
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:72
|
||||||
msgid "Set the language."
|
msgid "Set the language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:472
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:485
|
||||||
msgid "Set the publication date."
|
msgid "Set the publication date."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:476
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:489
|
||||||
msgid "Set the book timestamp (used by the date column in calibre)."
|
msgid "Set the book timestamp (used by the date column in calibre)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:576
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:589
|
||||||
msgid "Could not find an ebook inside the archive"
|
msgid "Could not find an ebook inside the archive"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:634
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:647
|
||||||
msgid "Values of series index and rating must be numbers. Ignoring"
|
msgid "Values of series index and rating must be numbers. Ignoring"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:641
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:654
|
||||||
msgid "Failed to parse date/time"
|
msgid "Failed to parse date/time"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:788
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:802
|
||||||
msgid "Converting input to HTML..."
|
msgid "Converting input to HTML..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:815
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:829
|
||||||
msgid "Running transforms on ebook..."
|
msgid "Running transforms on ebook..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:902
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:916
|
||||||
msgid "Creating"
|
msgid "Creating"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:58
|
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:205
|
||||||
msgid "Extract the contents of the generated EPUB file to the specified directory. The contents of the directory are first deleted, so be careful."
|
msgid "Extract the contents of the generated EPUB file to the specified directory. The contents of the directory are first deleted, so be careful."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:64
|
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:211
|
||||||
msgid "Turn off splitting at page breaks. Normally, input files are automatically split at every page break into two files. This gives an output ebook that can be parsed faster and with less resources. However, splitting is slow and if your source file contains a very large number of page breaks, you should turn off splitting on page breaks."
|
msgid "Turn off splitting at page breaks. Normally, input files are automatically split at every page break into two files. This gives an output ebook that can be parsed faster and with less resources. However, splitting is slow and if your source file contains a very large number of page breaks, you should turn off splitting on page breaks."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:75
|
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:222
|
||||||
msgid "Split all HTML files larger than this size (in KB). This is necessary as most EPUB readers cannot handle large file sizes. The default of %defaultKB is the size required for Adobe Digital Editions."
|
msgid "Split all HTML files larger than this size (in KB). This is necessary as most EPUB readers cannot handle large file sizes. The default of %defaultKB is the size required for Adobe Digital Editions."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:82
|
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:229
|
||||||
msgid "Normally, if the input file has no cover and you don't specify one, a default cover is generated with the title, authors, etc. This option disables the generation of this cover."
|
msgid "Normally, if the input file has no cover and you don't specify one, a default cover is generated with the title, authors, etc. This option disables the generation of this cover."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:88
|
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:235
|
||||||
msgid "Do not use SVG for the book cover. Use this option if your EPUB is going to be used ona device that does not support SVG, like the iPhone or the JetBook Lite. Without this option, such devices will display the cover as a blank page."
|
msgid "Do not use SVG for the book cover. Use this option if your EPUB is going to be used ona device that does not support SVG, like the iPhone or the JetBook Lite. Without this option, such devices will display the cover as a blank page."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:243
|
||||||
|
msgid "When using an SVG cover, this option will cause the cover to scale to cover the available screen area, but still preserve its aspect ratio (ratio of width to height). That means there may be white borders at the sides or top and bottom of the image, but the image will never be distorted. Without this option the image may be slightly distorted, but there will be no borders."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/fb2/fb2ml.py:144
|
#: /home/kovid/work/calibre/src/calibre/ebooks/fb2/fb2ml.py:144
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/rb/rbml.py:102
|
#: /home/kovid/work/calibre/src/calibre/ebooks/rb/rbml.py:102
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/txt/txtml.py:77
|
#: /home/kovid/work/calibre/src/calibre/ebooks/txt/txtml.py:77
|
||||||
@ -2026,19 +2046,19 @@ msgstr ""
|
|||||||
msgid "Split Options:"
|
msgid "Split Options:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/output.py:31
|
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/output.py:59
|
||||||
msgid "The unit of measure. Default is inch. Choices are %s Note: This does not override the unit for margins!"
|
msgid "The unit of measure. Default is inch. Choices are %s Note: This does not override the unit for margins!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/output.py:36
|
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/output.py:64
|
||||||
msgid "The size of the paper. This size will be overridden when an output profile is used. Default is letter. Choices are %s"
|
msgid "The size of the paper. This size will be overridden when an output profile is used. Default is letter. Choices are %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/output.py:40
|
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/output.py:68
|
||||||
msgid "Custom size of the document. Use the form widthxheight EG. `123x321` to specify the width and height. This overrides any specified paper-size."
|
msgid "Custom size of the document. Use the form widthxheight EG. `123x321` to specify the width and height. This overrides any specified paper-size."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/output.py:45
|
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/output.py:73
|
||||||
msgid "The orientation of the page. Default is portrait. Choices are %s"
|
msgid "The orientation of the page. Default is portrait. Choices are %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -2307,10 +2327,10 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_tab_template_ui.py:27
|
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_tab_template_ui.py:27
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:88
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:88
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:49
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:49
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:44
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:48
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_input_ui.py:28
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_input_ui.py:28
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_output_ui.py:28
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_output_ui.py:28
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:125
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:119
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:115
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:115
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:166
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:166
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:66
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:66
|
||||||
@ -2512,7 +2532,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:52
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:52
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:53
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:53
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:131
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:125
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:171
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:171
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:52
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:52
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:76
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:76
|
||||||
@ -2558,26 +2578,30 @@ msgstr ""
|
|||||||
msgid "EPUB Output"
|
msgid "EPUB Output"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:45
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:49
|
||||||
msgid "Do not &split on page breaks"
|
msgid "Do not &split on page breaks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:46
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:50
|
||||||
msgid "Split files &larger than:"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:47
|
|
||||||
msgid " KB"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:48
|
|
||||||
msgid "No default &cover"
|
msgid "No default &cover"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:49
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:51
|
||||||
msgid "No &SVG cover"
|
msgid "No &SVG cover"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:52
|
||||||
|
msgid "Preserve cover &aspect ratio"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:53
|
||||||
|
msgid "Split files &larger than:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:54
|
||||||
|
msgid " KB"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_input.py:12
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_input.py:12
|
||||||
msgid "FB2 Input"
|
msgid "FB2 Input"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -2618,15 +2642,15 @@ msgid "&Base font size:"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:105
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:105
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:129
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:123
|
||||||
msgid "Font size &key:"
|
msgid "Font size &key:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:106
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:106
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:110
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:110
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:112
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:112
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:128
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:122
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:133
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:127
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:118
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:118
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:120
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:120
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:125
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:125
|
||||||
@ -2665,72 +2689,76 @@ msgstr ""
|
|||||||
msgid "Control the look and feel of the output"
|
msgid "Control the look and feel of the output"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:126
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel.py:30
|
||||||
|
msgid "Original"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel.py:31
|
||||||
|
msgid "Left align"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel.py:32
|
||||||
|
msgid "Justify text"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:120
|
||||||
msgid "&Disable font size rescaling"
|
msgid "&Disable font size rescaling"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:127
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:121
|
||||||
msgid "Base &font size:"
|
msgid "Base &font size:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:130
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:124
|
||||||
msgid "Wizard to help you choose an appropriate font size key"
|
msgid "Wizard to help you choose an appropriate font size key"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:132
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:126
|
||||||
msgid "Line &height:"
|
msgid "Line &height:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:134
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:128
|
||||||
msgid "Input character &encoding:"
|
msgid "Input character &encoding:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:135
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:129
|
||||||
msgid "Remove &spacing between paragraphs"
|
msgid "Remove &spacing between paragraphs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:136
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:130
|
||||||
msgid "Indent size:"
|
msgid "Indent size:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:137
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:131
|
||||||
msgid "<p>When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent."
|
msgid "<p>When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:138
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:132
|
||||||
msgid " em"
|
msgid " em"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:139
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:133
|
||||||
msgid "&Linearize tables"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:140
|
|
||||||
msgid "&Transliterate unicode characters to ASCII."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:141
|
|
||||||
msgid "Extra &CSS"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:142
|
|
||||||
msgid "Insert &blank line"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:143
|
|
||||||
msgid "Text justification:"
|
msgid "Text justification:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:144
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:134
|
||||||
msgid "justify"
|
msgid "&Linearize tables"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:145
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:135
|
||||||
msgid "left"
|
msgid "Extra &CSS"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:146
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:136
|
||||||
msgid "original"
|
msgid "&Transliterate unicode characters to ASCII"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:137
|
||||||
|
msgid "Insert &blank line"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:138
|
||||||
|
msgid "Keep &ligatures"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output.py:19
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output.py:19
|
||||||
@ -7833,18 +7861,22 @@ msgid "English (Ireland)"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:109
|
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:109
|
||||||
msgid "Spanish (Paraguay)"
|
msgid "English (China)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:110
|
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:110
|
||||||
msgid "German (AT)"
|
msgid "Spanish (Paraguay)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:111
|
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:111
|
||||||
msgid "Dutch (NL)"
|
msgid "German (AT)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:112
|
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:112
|
||||||
|
msgid "Dutch (NL)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:113
|
||||||
msgid "Dutch (BE)"
|
msgid "Dutch (BE)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -7868,13 +7900,13 @@ msgstr ""
|
|||||||
msgid "Control email delivery"
|
msgid "Control email delivery"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
|
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:113
|
||||||
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
|
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:135
|
||||||
msgid "Unknown feed"
|
msgid "Unknown feed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:142
|
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:153
|
||||||
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:165
|
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:178
|
||||||
msgid "Untitled article"
|
msgid "Untitled article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -7970,23 +8002,23 @@ msgstr ""
|
|||||||
msgid "Untitled Article"
|
msgid "Untitled Article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1228
|
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1230
|
||||||
msgid "Article downloaded: %s"
|
msgid "Article downloaded: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1239
|
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1241
|
||||||
msgid "Article download failed: %s"
|
msgid "Article download failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1256
|
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1258
|
||||||
msgid "Fetching feed"
|
msgid "Fetching feed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1403
|
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1405
|
||||||
msgid "Failed to log in, check your username and password for the calibre Periodicals service."
|
msgid "Failed to log in, check your username and password for the calibre Periodicals service."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1419
|
#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:1421
|
||||||
msgid "You do not have permission to download this issue. Either your subscription has expired or you have exceeded the maximum allowed downloads for today."
|
msgid "You do not have permission to download this issue. Either your subscription has expired or you have exceeded the maximum allowed downloads for today."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -49,6 +49,17 @@ class Article(object):
|
|||||||
self.date = published
|
self.date = published
|
||||||
self.utctime = dt_factory(self.date, assume_utc=True, as_utc=True)
|
self.utctime = dt_factory(self.date, assume_utc=True, as_utc=True)
|
||||||
self.localtime = self.utctime.astimezone(local_tz)
|
self.localtime = self.utctime.astimezone(local_tz)
|
||||||
|
self._formatted_date = None
|
||||||
|
|
||||||
|
@dynamic_property
|
||||||
|
def formatted_date(self):
|
||||||
|
def fget(self):
|
||||||
|
if self._formatted_date is None:
|
||||||
|
self._formatted_date = self.localtime.strftime(" [%a, %d %b %H:%M]")
|
||||||
|
return self._formatted_date
|
||||||
|
def fset(self, val):
|
||||||
|
self._formatted_date = val
|
||||||
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
@dynamic_property
|
@dynamic_property
|
||||||
def title(self):
|
def title(self):
|
||||||
@ -150,6 +161,8 @@ class Feed(object):
|
|||||||
self.articles.append(article)
|
self.articles.append(article)
|
||||||
else:
|
else:
|
||||||
self.logger.debug('Skipping article %s (%s) from feed %s as it is too old.'%(title, article.localtime.strftime('%a, %d %b, %Y %H:%M'), self.title))
|
self.logger.debug('Skipping article %s (%s) from feed %s as it is too old.'%(title, article.localtime.strftime('%a, %d %b, %Y %H:%M'), self.title))
|
||||||
|
d = item.get('date', '')
|
||||||
|
article.formatted_date = d
|
||||||
|
|
||||||
|
|
||||||
def parse_article(self, item):
|
def parse_article(self, item):
|
||||||
|
@ -1179,6 +1179,8 @@ class BasicNewsRecipe(Recipe):
|
|||||||
body.insert(len(body.contents), elem)
|
body.insert(len(body.contents), elem)
|
||||||
with open(last, 'wb') as fi:
|
with open(last, 'wb') as fi:
|
||||||
fi.write(unicode(soup).encode('utf-8'))
|
fi.write(unicode(soup).encode('utf-8'))
|
||||||
|
if len(feeds) == 0:
|
||||||
|
raise Exception('All feeds are empty, aborting.')
|
||||||
|
|
||||||
if len(feeds) > 1:
|
if len(feeds) > 1:
|
||||||
for i, f in enumerate(feeds):
|
for i, f in enumerate(feeds):
|
||||||
|
@ -160,7 +160,7 @@ class FeedTemplate(Template):
|
|||||||
<li id="${'article_%d'%i}" py:if="getattr(article, 'downloaded',
|
<li id="${'article_%d'%i}" py:if="getattr(article, 'downloaded',
|
||||||
False)" style="padding-bottom:0.5em" class="calibre_rescale_100">
|
False)" style="padding-bottom:0.5em" class="calibre_rescale_100">
|
||||||
<a class="article calibre_rescale_120" href="${article.url}">${article.title}</a>
|
<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.formatted_date}</span>
|
||||||
<div class="article_description calibre_rescale_70" py:if="article.summary">
|
<div class="article_description calibre_rescale_70" py:if="article.summary">
|
||||||
${Markup(cutoff(article.text_summary))}
|
${Markup(cutoff(article.text_summary))}
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user