This commit is contained in:
Sengian 2011-11-13 17:50:47 +01:00
commit 29c85bb4f5
10 changed files with 542 additions and 307 deletions

View File

@ -1,26 +1,27 @@
# adapted from old recipe by Darko Miletic <darko.miletic at gmail.com> # adapted from old recipe by Darko Miletic <darko.miletic at gmail.com>
import re import string, re
from calibre import strftime
from calibre.web.feeds.recipes import BasicNewsRecipe from calibre.web.feeds.recipes import BasicNewsRecipe
from calibre.ebooks.BeautifulSoup import Tag, NavigableString from calibre.ebooks.BeautifulSoup import BeautifulSoup, Tag, NavigableString
class TheIndependentNew(BasicNewsRecipe): class TheIndependentNew(BasicNewsRecipe):
# flag to enable/disable article graphics on business pages/some others # flag to enable/disable article graphics on business pages/some others
# eg http://www.independent.co.uk/news/world/europe/berlusconi-departure-fails-to-calm-the-markets-6259682.html # eg http://www.independent.co.uk/news/world/europe/berlusconi-departure-fails-to-calm-the-markets-6259682.html
# -max dimensions can be altered using the .pictureContainer img selector in the css # -max dimensions can be altered using the .pictureContainer img selector in the css
_FETCH_ARTICLE_GRAPHICS = True _FETCH_ARTICLE_GRAPHICS = True
#Flag to enable/disable image fetching (not business) #Flag to enable/disable image fetching (not business)
_FETCH_IMAGES = True _FETCH_IMAGES = True
#used for converting rating to stars #used for converting rating to stars
_STAR_URL = 'http://www.independent.co.uk/skins/ind/images/rating_star.png' _STAR_URL = 'http://www.independent.co.uk/skins/ind/images/rating_star.png'
_NO_STAR_URL = 'http://www.independent.co.uk/skins/ind/images/rating_star_grey.png' _NO_STAR_URL = 'http://www.independent.co.uk/skins/ind/images/rating_star_grey.png'
title = u'The Independent' title = u'The Independent'
__author__ = 'Will' __author__ = 'Will'
description = 'The latest in UK News and World News from The \ description = 'The latest in UK News and World News from The \
@ -41,26 +42,26 @@ class TheIndependentNew(BasicNewsRecipe):
dict(attrs={'id' : ['RelatedArtTag','renderBiography']}), dict(attrs={'id' : ['RelatedArtTag','renderBiography']}),
dict(attrs={'class' : ['autoplay','openBiogPopup']}) dict(attrs={'class' : ['autoplay','openBiogPopup']})
] ]
keep_only_tags =[dict(attrs={'id':'main'})] keep_only_tags =[dict(attrs={'id':'main'})]
recursions = 0 recursions = 0
# fixes non compliant html nesting and 'marks' article graphics links # fixes non compliant html nesting and 'marks' article graphics links
preprocess_regexps = [ preprocess_regexps = [
(re.compile('<span class="storyTop ">(?P<nested>.*?)</span>', re.DOTALL), (re.compile('<span class="storyTop ">(?P<nested>.*?)</span>', re.DOTALL),
lambda match: '<div class="storyTop">' + match.group('nested') + '</div>'), lambda match: '<div class="storyTop">' + match.group('nested') + '</div>'),
(re.compile('<strong>.*?Click.*?to view graphic.*?</strong>', re.DOTALL), (re.compile('(<strong>.*?[Cc]lick.*?<a.*?((HERE)|([Hh]ere)).*?</strong>)', re.DOTALL),
lambda match: '<div class="article-graphic">' + match.group(0) + '</div>'), lambda match: '<div class="article-graphic">' + match.group(0) + '</div>'),
] ]
conversion_options = { conversion_options = {
'comment' : description 'comment' : description
, 'tags' : category , 'tags' : category
, 'publisher' : publisher , 'publisher' : publisher
, 'language' : language , 'language' : language
} }
extra_css = """ extra_css = """
h1{font-family: Georgia,serif } h1{font-family: Georgia,serif }
body{font-family: Verdana,Arial,Helvetica,sans-serif} body{font-family: Verdana,Arial,Helvetica,sans-serif}
@ -80,22 +81,22 @@ class TheIndependentNew(BasicNewsRecipe):
.articleContent {display: block; clear:left;} .articleContent {display: block; clear:left;}
.storyTop{} .storyTop{}
.pictureContainer img { max-width: 400px; max-height: 400px;} .pictureContainer img { max-width: 400px; max-height: 400px;}
""" """
oldest_article = 1 oldest_article = 1
max_articles_per_feed = 100 max_articles_per_feed = 100
_processed_urls = [] _processed_urls = []
def get_article_url(self, article): def get_article_url(self, article):
url = super(self.__class__,self).get_article_url(article) url = super(self.__class__,self).get_article_url(article)
title = article.get('title', None) title = article.get('title', None)
if title and re.search("^Video:",title): if title and re.search("^Video:",title):
return None return None
#remove duplicates #remove duplicates
if not (url in self._processed_urls): if not (url in self._processed_urls):
self._processed_urls.append(url) self._processed_urls.append(url)
else: else:
@ -103,132 +104,147 @@ class TheIndependentNew(BasicNewsRecipe):
return url return url
def preprocess_html(self, soup): def preprocess_html(self, soup):
#remove 'advertorial articles'
strapline = soup.find('div',attrs={'class' : re.compile('.*strapLine.*')})
if strapline:
for para in strapline.findAll('p'):
if len(para.contents) and isinstance(para.contents[0],NavigableString) \
and para.contents[0] == 'ADVERTORIAL FEATURE':
return None
items_to_extract = [] items_to_extract = []
for item in soup.findAll(attrs={'class' : re.compile("widget.*")}): for item in soup.findAll(attrs={'class' : re.compile("widget.*")}):
remove = True remove = True
pattern = re.compile('((articleContent)|(title))$') pattern = re.compile('((articleContent)|(title))$')
if (pattern.search(item['class'])) is not None: if (pattern.search(item['class'])) is not None:
remove = False remove = False
# corrections # corrections
# story content always good # story content always good
pattern = re.compile('storyContent') pattern = re.compile('storyContent')
if (pattern.search(item['class'])) is not None: if (pattern.search(item['class'])) is not None:
remove = False remove = False
#images #images
pattern = re.compile('slideshow') pattern = re.compile('slideshow')
if (pattern.search(item['class'])) is not None: if (pattern.search(item['class'])) is not None:
if self._FETCH_IMAGES: if self._FETCH_IMAGES:
remove = False remove = False
else: else:
remove = True remove = True
#social widgets always bad #social widgets always bad
pattern = re.compile('socialwidget') pattern = re.compile('socialwidget')
if (pattern.search(item['class'])) is not None: if (pattern.search(item['class'])) is not None:
remove = True remove = True
if remove: if remove:
items_to_extract.append(item) items_to_extract.append(item)
for item in items_to_extract: for item in items_to_extract:
item.extract() item.extract()
items_to_extract = [] items_to_extract = []
if self._FETCH_IMAGES: if self._FETCH_IMAGES:
for item in soup.findAll('a',attrs={'href' : re.compile('.*')}): for item in soup.findAll('a',attrs={'href' : re.compile('.*')}):
if item.img is not None: if item.img is not None:
#use full size image #use full size image
img = item.findNext('img') img = item.findNext('img')
img['src'] = item['href'] img['src'] = item['href']
#insert caption if available #insert caption if available
if img['title'] is not None and (len(img['title']) > 1): if img['title'] is not None and (len(img['title']) > 1):
tag = Tag(soup,'h3') tag = Tag(soup,'h3')
text = NavigableString(img['title']) text = NavigableString(img['title'])
tag.insert(0,text) tag.insert(0,text)
#picture before text #picture before text
img.extract() img.extract()
item.insert(0,img) item.insert(0,img)
item.insert(1,tag) item.insert(1,tag)
# remove link # remove link
item.name = "div" item.name = "div"
item["class"]='image' item["class"]='image'
del item["href"] del item["href"]
#remove empty subtitles #remove empty subtitles
""" """
currently the subtitle is located in first paragraph after currently the subtitle is located in first paragraph after
sibling <h3 class="subtitle"> tag. This may be 'fixed' at sibling <h3 class="subtitle"> tag. This may be 'fixed' at
some point. some point.
""" """
subtitle = soup.find('h3',attrs={'class' : 'subtitle'}) subtitle = soup.find('h3',attrs={'class' : 'subtitle'})
if subtitle is not None: if subtitle is not None:
subtitleText = subtitle.findNext('p') subtitleText = subtitle.findNext('p')
if subtitleText is not None: if subtitleText is not None:
if len(subtitleText.contents[0]) <= 1 : if len(subtitleText.contents[0]) <= 1 :
subtitleText.extract() subtitleText.extract()
subtitle.extract() subtitle.extract()
#replace rating numbers with stars #replace rating numbers with stars
for item in soup.findAll('div',attrs={ 'class' : 'starRating'}): for item in soup.findAll('div',attrs={ 'class' : 'starRating'}):
if item is not None: if item is not None:
soup2 = self._insertRatingStars(soup,item) soup2 = self._insertRatingStars(soup,item)
if soup2 is not None: if soup2 is not None:
soup = soup2 soup = soup2
#remove empty paragraph tags in storyTop which can leave a space #remove empty paragraph tags in storyTop which can leave a space
#between first paragraph and rest of story #between first paragraph and rest of story
nested_content = False
storyTop = soup.find('div',attrs={ 'class' : ['storyTop']}) storyTop = soup.find('div',attrs={ 'class' : ['storyTop']})
for item in storyTop.findAll('p'): for item in storyTop.findAll('p'):
if item.contents is not None and len(item.contents[0]) <= 1 : for nested in item:
if isinstance(nested, Tag):
nested_content = True
break
if not nested_content and item.contents is not None and len(item.contents[0]) <= 1 :
items_to_extract.append(item) items_to_extract.append(item)
for item in items_to_extract: for item in items_to_extract:
item.extract() item.extract()
items_to_extract = [] items_to_extract = []
#remove line breaks immediately next to tags with default margins #remove line breaks immediately next to tags with default margins
#to prevent double line spacing and narrow columns of text #to prevent double line spacing and narrow columns of text
storyTop = soup.find('div',attrs={ 'class' : ['storyTop']}) storyTop = soup.find('div',attrs={ 'class' : ['storyTop']})
self._remove_undesired_line_breaks_from_tag(storyTop,soup) self._remove_undesired_line_breaks_from_tag(storyTop,soup)
#replace article graphics link with the graphics themselves #replace article graphics link with the graphics themselves
if self._FETCH_ARTICLE_GRAPHICS: if self._FETCH_ARTICLE_GRAPHICS:
items_to_insert = [] items_to_insert = []
for item in soup.findAll('div', attrs={'class' : ['article-graphic']}): for item in soup.findAll('div', attrs={'class' : ['article-graphic']}):
strong = item.find('strong') strong = item.find('strong')
if not strong:
continue
for child in strong: for child in strong:
if isinstance(child,Tag): if isinstance(child,Tag):
if str(child.name) == 'a': if str(child.name) == 'a':
items_to_insert.extend(self._get_article_graphic(strong,child['href'],soup)) items_to_insert.extend(self._get_article_graphic(strong,child['href'],soup))
for item in items_to_insert: for item in items_to_insert:
item[0].replaceWith(item[1]) item[0].replaceWith(item[1])
for item in items_to_extract: for item in items_to_extract:
item.extract() item.extract()
return soup return soup
def _get_article_graphic(self,old_item,url,soup): def _get_article_graphic(self,old_item,url,soup):
items_to_insert = [] items_to_insert = []
if re.search('\.jpg$',str(url)): if re.search('\.jpg$',str(url)):
div = Tag(soup,'div') div = Tag(soup,'div')
div['class'] = 'pictureContainer' div['class'] = 'pictureContainer'
@ -238,20 +254,20 @@ class TheIndependentNew(BasicNewsRecipe):
div.insert(0,img) div.insert(0,img)
items_to_insert.append((old_item,div,)) items_to_insert.append((old_item,div,))
return items_to_insert return items_to_insert
soup2 = self.index_to_soup(url) soup2 = self.index_to_soup(url)
for item in soup2.findAll('div',attrs={'class' : re.compile("widget picture article.*")}): for item in soup2.findAll('div',attrs={'class' : re.compile("widget picture article.*")}):
items_to_insert.append((old_item,item),) items_to_insert.append((old_item,item),)
return items_to_insert return items_to_insert
def _insertRatingStars(self,soup,item): def _insertRatingStars(self,soup,item):
if item.contents is None: if item.contents is None:
return return
rating = item.contents[0] rating = item.contents[0]
if not rating.isdigit(): if not rating.isdigit():
return None return None
rating = int(item.contents[0]) rating = int(item.contents[0])
for i in range(1,6): for i in range(1,6):
star = Tag(soup,'img') star = Tag(soup,'img')
if i <= rating: if i <= rating:
@ -261,26 +277,26 @@ class TheIndependentNew(BasicNewsRecipe):
star['alt'] = 'star number ' + str(i) star['alt'] = 'star number ' + str(i)
item.insert(i,star) item.insert(i,star)
#item.contents[0] = NavigableString('(' + str(rating) + ')') #item.contents[0] = NavigableString('(' + str(rating) + ')')
item.contents[0] = '' item.contents[0] = ''
def postprocess_html(self,soup, first_fetch): def postprocess_html(self,soup, first_fetch):
#find broken images and remove captions #find broken images and remove captions
items_to_extract = [] items_to_extract = []
for item in soup.findAll('div', attrs={'class' : 'image'}): for item in soup.findAll('div', attrs={'class' : 'image'}):
img = item.findNext('img') img = item.findNext('img')
if img is not None and img['src'] is not None: if img is not None and img['src'] is not None:
# broken images still point to remote url # broken images still point to remote url
pattern = re.compile('http://www.independent.co.uk.*') pattern = re.compile('http://www.independent.co.uk.*')
if pattern.match(img["src"]) is not None: if pattern.match(img["src"]) is not None:
caption = img.findNextSibling('h3') caption = img.findNextSibling('h3')
if caption is not None: if caption is not None:
items_to_extract.append(caption) items_to_extract.append(caption)
items_to_extract.append(img) items_to_extract.append(img)
for item in items_to_extract: for item in items_to_extract:
item.extract() item.extract()
return soup return soup
def _recurisvely_linearise_tag_tree( def _recurisvely_linearise_tag_tree(
self, self,
item, item,
@ -295,25 +311,25 @@ class TheIndependentNew(BasicNewsRecipe):
if not (isinstance(item,Tag)): if not (isinstance(item,Tag)):
return linearised return linearised
for nested in item: for nested in item:
linearised.append(nested) linearised.append(nested)
linearised = self._recurisvely_linearise_tag_tree(nested,linearised, count) linearised = self._recurisvely_linearise_tag_tree(nested,linearised, count)
return linearised return linearised
def _get_previous_tag(self,current_index, tag_tree): def _get_previous_tag(self,current_index, tag_tree):
if current_index == 0: if current_index == 0:
return None return None
else: else:
return tag_tree[current_index - 1] return tag_tree[current_index - 1]
def _get_next_tag(self,current_index, tag_tree): def _get_next_tag(self,current_index, tag_tree):
if current_index < len(tag_tree) - 1: if current_index < len(tag_tree) - 1:
return tag_tree[current_index + 1] return tag_tree[current_index + 1]
else: else:
return None return None
def _list_match(self,test_str, list_regex): def _list_match(self,test_str, list_regex):
for regex in list_regex: for regex in list_regex:
match = re.match(regex, test_str) match = re.match(regex, test_str)
@ -322,24 +338,24 @@ class TheIndependentNew(BasicNewsRecipe):
return False return False
def _remove_undesired_line_breaks_from_tag(self,parent,soup): def _remove_undesired_line_breaks_from_tag(self,parent,soup):
if parent is None: if parent is None:
return return
tag_tree = self._recurisvely_linearise_tag_tree(parent) tag_tree = self._recurisvely_linearise_tag_tree(parent)
items_to_remove = [] items_to_remove = []
for item in tag_tree: for item in tag_tree:
if item == u'\n': if item == u'\n':
items_to_remove.append(item) items_to_remove.append(item)
continue; continue;
for item in items_to_remove: for item in items_to_remove:
tag_tree.remove(item) tag_tree.remove(item)
spaced_tags = [r'p', r'h\d', r'blockquote'] spaced_tags = [r'p', r'h\d', r'blockquote']
tags_to_extract = [] tags_to_extract = []
tags_to_replace = [] tags_to_replace = []
@ -347,41 +363,41 @@ class TheIndependentNew(BasicNewsRecipe):
if isinstance(tag, Tag): if isinstance(tag, Tag):
if str(tag) == '<br />': if str(tag) == '<br />':
previous_tag = self._get_previous_tag(i, tag_tree) previous_tag = self._get_previous_tag(i, tag_tree)
if isinstance(previous_tag, Tag): if isinstance(previous_tag, Tag):
previous_tag_is_spaced = previous_tag is not None\ previous_tag_is_spaced = previous_tag is not None\
and self._list_match(str(previous_tag.name), and self._list_match(str(previous_tag.name),
spaced_tags) spaced_tags)
else: else:
previous_tag_is_spaced = False previous_tag_is_spaced = False
next_tag = self._get_next_tag(i, tag_tree) next_tag = self._get_next_tag(i, tag_tree)
if isinstance(next_tag, Tag): if isinstance(next_tag, Tag):
next_tag_is_spaced = next_tag is not None\ next_tag_is_spaced = next_tag is not None\
and self._list_match(str(next_tag.name), spaced_tags) and self._list_match(str(next_tag.name), spaced_tags)
else: else:
next_tag_is_spaced = False next_tag_is_spaced = False
if previous_tag_is_spaced or next_tag_is_spaced or i == 0\ if previous_tag_is_spaced or next_tag_is_spaced or i == 0\
or i == len(tag_tree) - 1: or i == len(tag_tree) - 1:
tags_to_extract.append(tag) tags_to_extract.append(tag)
else: else:
tags_to_replace.append((tag,NavigableString(' '),)) tags_to_replace.append((tag,NavigableString(' '),))
for pair in tags_to_replace: for pair in tags_to_replace:
pair[0].replaceWith(pair[1]) pair[0].replaceWith(pair[1])
for tag in tags_to_extract: for tag in tags_to_extract:
tag.extract() tag.extract()
feeds = [ feeds = [
(u'News - UK', (u'News - UK',
u'http://www.independent.co.uk/news/uk/?service=rss'), u'http://www.independent.co.uk/news/uk/?service=rss'),
(u'News - World', (u'News - World',
u'http://www.independent.co.uk/news/world/?service=rss'), u'http://www.independent.co.uk/news/world/?service=rss'),
(u'News - Business', (u'News - Business',
u'http://www.independent.co.uk/news/business/?service=rss'), u'http://www.independent.co.uk/news/business/?service=rss'),
(u'News - People', (u'News - People',
u'http://www.independent.co.uk/news/people/?service=rss'), u'http://www.independent.co.uk/news/people/?service=rss'),
(u'News - Science', (u'News - Science',
@ -481,4 +497,4 @@ class TheIndependentNew(BasicNewsRecipe):
(u'IndyBest', (u'IndyBest',
u'http://www.independent.co.uk/extras/indybest/?service=rss'), u'http://www.independent.co.uk/extras/indybest/?service=rss'),
] ]

View File

@ -3,7 +3,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
''' '''
Fetch sueddeutsche. Fetch sueddeutsche.de
''' '''
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
@ -62,7 +62,7 @@ class Sueddeutsche(BasicNewsRecipe):
(u'Sport', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5ESport%24?output=rss'), (u'Sport', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5ESport%24?output=rss'),
(u'Leben', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5ELeben%24?output=rss'), (u'Leben', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5ELeben%24?output=rss'),
(u'Karriere', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5EKarriere%24?output=rss'), (u'Karriere', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5EKarriere%24?output=rss'),
(u'M&uuml;nchen & Region', u'http://www.sueddeutsche.de/app/service/rss/ressort/muenchen/rss.xml'), (u'München & Region', u'http://www.sueddeutsche.de/app/service/rss/ressort/muenchen/rss.xml'), # AGe 2011-11-13
(u'Bayern', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5EBayern%24?output=rss'), (u'Bayern', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5EBayern%24?output=rss'),
(u'Medien', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5EMedien%24?output=rss'), (u'Medien', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5EMedien%24?output=rss'),
(u'Digital', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5EDigital%24?output=rss'), (u'Digital', u'http://suche.sueddeutsche.de/query/%23/sort/-docdatetime/drilldown/%C2%A7ressort%3A%5EDigital%24?output=rss'),

View File

@ -134,7 +134,7 @@ def add_pipeline_options(parser, plumber):
'font_size_mapping', 'font_size_mapping',
'line_height', 'minimum_line_height', 'line_height', 'minimum_line_height',
'linearize_tables', 'linearize_tables',
'extra_css', 'extra_css', 'filter_css',
'smarten_punctuation', 'unsmarten_punctuation', 'smarten_punctuation', 'unsmarten_punctuation',
'margin_top', 'margin_left', 'margin_right', 'margin_top', 'margin_left', 'margin_right',
'margin_bottom', 'change_justification', 'margin_bottom', 'change_justification',

View File

@ -308,6 +308,16 @@ OptionRecommendation(name='extra_css',
'rules.') 'rules.')
), ),
OptionRecommendation(name='filter_css',
recommended_value=None, level=OptionRecommendation.LOW,
help=_('A comma separated list of CSS properties that '
'will be removed from all CSS style rules. This is useful '
'if the presence of some style information prevents it '
'from being overridden on your device. '
'For example: '
'font-family,color,margin-left,margin-right')
),
OptionRecommendation(name='page_breaks_before', OptionRecommendation(name='page_breaks_before',
recommended_value="//*[name()='h1' or name()='h2']", recommended_value="//*[name()='h1' or name()='h2']",
level=OptionRecommendation.LOW, level=OptionRecommendation.LOW,

View File

@ -118,8 +118,20 @@ class CSSFlattener(object):
def __call__(self, oeb, context): def __call__(self, oeb, context):
oeb.logger.info('Flattening CSS and remapping font sizes...') oeb.logger.info('Flattening CSS and remapping font sizes...')
self.context = self.opts =context
self.oeb = oeb self.oeb = oeb
self.context = context
self.filter_css = frozenset()
if self.opts.filter_css:
try:
self.filter_css = frozenset([x.strip().lower() for x in
self.opts.filter_css.split(',')])
except:
self.oeb.log.warning('Failed to parse filter_css, ignoring')
else:
self.oeb.log.debug('Filtering CSS properties: %s'%
', '.join(self.filter_css))
self.stylize_spine() self.stylize_spine()
self.sbase = self.baseline_spine() if self.fbase else None self.sbase = self.baseline_spine() if self.fbase else None
self.fmap = FontMapper(self.sbase, self.fbase, self.fkey) self.fmap = FontMapper(self.sbase, self.fbase, self.fkey)
@ -279,6 +291,10 @@ class CSSFlattener(object):
except: except:
self.oeb.logger.exception('Failed to set minimum line-height') self.oeb.logger.exception('Failed to set minimum line-height')
if cssdict:
for x in self.filter_css:
cssdict.pop(x, None)
if cssdict: if cssdict:
if self.lineh and self.fbase and tag != 'body': if self.lineh and self.fbase and tag != 'body':
self.clean_edges(cssdict, style, psize) self.clean_edges(cssdict, style, psize)
@ -311,7 +327,6 @@ class CSSFlattener(object):
lineh = self.lineh / psize lineh = self.lineh / psize
cssdict['line-height'] = "%0.5fem" % lineh cssdict['line-height'] = "%0.5fem" % lineh
if (self.context.remove_paragraph_spacing or if (self.context.remove_paragraph_spacing or
self.context.insert_blank_line) and tag in ('p', 'div'): self.context.insert_blank_line) and tag in ('p', 'div'):
if item_id != 'calibre_jacket' or self.context.output_profile.name == 'Kindle': if item_id != 'calibre_jacket' or self.context.output_profile.name == 'Kindle':

View File

@ -18,6 +18,16 @@ class LookAndFeelWidget(Widget, Ui_Form):
HELP = _('Control the look and feel of the output') HELP = _('Control the look and feel of the output')
COMMIT_NAME = 'look_and_feel' COMMIT_NAME = 'look_and_feel'
FILTER_CSS = {
'fonts': {'font-family'},
'margins': {'margin', 'margin-left', 'margin-right', 'margin-top',
'margin-bottom'},
'padding': {'padding', 'padding-left', 'padding-right', 'padding-top',
'padding-bottom'},
'floats': {'float'},
'colors': {'color', 'background', 'background-color'},
}
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, Widget.__init__(self, parent,
['change_justification', 'extra_css', 'base_font_size', ['change_justification', 'extra_css', 'base_font_size',
@ -27,7 +37,7 @@ class LookAndFeelWidget(Widget, Ui_Form):
'remove_paragraph_spacing', 'remove_paragraph_spacing',
'remove_paragraph_spacing_indent_size', 'remove_paragraph_spacing_indent_size',
'insert_blank_line_size', 'insert_blank_line_size',
'input_encoding', 'input_encoding', 'filter_css',
'asciiize', 'keep_ligatures', 'asciiize', 'keep_ligatures',
'linearize_tables'] 'linearize_tables']
) )
@ -56,6 +66,15 @@ class LookAndFeelWidget(Widget, Ui_Form):
if g is self.opt_change_justification: if g is self.opt_change_justification:
ans = unicode(g.itemData(g.currentIndex()).toString()) ans = unicode(g.itemData(g.currentIndex()).toString())
return ans return ans
if g is self.opt_filter_css:
ans = set()
for key, item in self.FILTER_CSS.iteritems():
w = getattr(self, 'filter_css_%s'%key)
if w.isChecked():
ans = ans.union(item)
ans = ans.union(set([x.strip().lower() for x in
unicode(self.filter_css_others.text()).split(',')]))
return ','.join(ans) if ans else None
return Widget.get_value_handler(self, g) return Widget.get_value_handler(self, g)
def set_value_handler(self, g, val): def set_value_handler(self, g, val):
@ -66,6 +85,27 @@ class LookAndFeelWidget(Widget, Ui_Form):
g.setCurrentIndex(i) g.setCurrentIndex(i)
break break
return True return True
if g is self.opt_filter_css:
if not val: val = ''
items = frozenset([x.strip().lower() for x in val.split(',')])
for key, vals in self.FILTER_CSS.iteritems():
w = getattr(self, 'filter_css_%s'%key)
if not vals - items:
items = items - vals
w.setChecked(True)
else:
w.setChecked(False)
self.filter_css_others.setText(', '.join(items))
return True
def connect_gui_obj_handler(self, gui_obj, slot):
if gui_obj is self.opt_filter_css:
for key in self.FILTER_CSS:
w = getattr(self, 'filter_css_%s'%key)
w.stateChanged.connect(slot)
self.filter_css_others.textChanged.connect(slot)
return
raise NotImplementedError()
def font_key_wizard(self): def font_key_wizard(self):
from calibre.gui2.convert.font_key import FontKeyChooser from calibre.gui2.convert.font_key import FontKeyChooser

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>642</width> <width>655</width>
<height>522</height> <height>522</height>
</rect> </rect>
</property> </property>
@ -164,6 +164,41 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="3">
<widget class="QLabel" name="label_4">
<property name="text">
<string>&amp;Indent size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>opt_remove_paragraph_spacing_indent_size</cstring>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QDoubleSpinBox" name="opt_remove_paragraph_spacing_indent_size">
<property name="toolTip">
<string>&lt;p&gt;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.</string>
</property>
<property name="specialValueText">
<string>No change</string>
</property>
<property name="suffix">
<string> em</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2"> <item row="7" column="0" colspan="2">
<widget class="QCheckBox" name="opt_insert_blank_line"> <widget class="QCheckBox" name="opt_insert_blank_line">
<property name="text"> <property name="text">
@ -171,6 +206,19 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="3">
<widget class="QLabel" name="label_7">
<property name="text">
<string>&amp;Line size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>opt_insert_blank_line_size</cstring>
</property>
</widget>
</item>
<item row="7" column="4"> <item row="7" column="4">
<widget class="QDoubleSpinBox" name="opt_insert_blank_line_size"> <widget class="QDoubleSpinBox" name="opt_insert_blank_line_size">
<property name="suffix"> <property name="suffix">
@ -194,80 +242,6 @@
<item row="8" column="2" colspan="3"> <item row="8" column="2" colspan="3">
<widget class="QComboBox" name="opt_change_justification"/> <widget class="QComboBox" name="opt_change_justification"/>
</item> </item>
<item row="9" column="1" colspan="4">
<widget class="QCheckBox" name="opt_asciiize">
<property name="text">
<string>&amp;Transliterate unicode characters to ASCII</string>
</property>
</widget>
</item>
<item row="10" column="1" colspan="2">
<widget class="QCheckBox" name="opt_keep_ligatures">
<property name="text">
<string>Keep &amp;ligatures</string>
</property>
</widget>
</item>
<item row="13" column="0" colspan="5">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Extra &amp;CSS</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QTextEdit" name="opt_extra_css"/>
</item>
</layout>
</widget>
</item>
<item row="6" column="4">
<widget class="QDoubleSpinBox" name="opt_remove_paragraph_spacing_indent_size">
<property name="toolTip">
<string>&lt;p&gt;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.</string>
</property>
<property name="specialValueText">
<string>No change</string>
</property>
<property name="suffix">
<string> em</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="6" column="3">
<widget class="QLabel" name="label_4">
<property name="text">
<string>&amp;Indent size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>opt_remove_paragraph_spacing_indent_size</cstring>
</property>
</widget>
</item>
<item row="7" column="3">
<widget class="QLabel" name="label_7">
<property name="text">
<string>&amp;Line size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>opt_insert_blank_line_size</cstring>
</property>
</widget>
</item>
<item row="9" column="0"> <item row="9" column="0">
<widget class="QCheckBox" name="opt_smarten_punctuation"> <widget class="QCheckBox" name="opt_smarten_punctuation">
<property name="text"> <property name="text">
@ -275,6 +249,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="1" colspan="4">
<widget class="QCheckBox" name="opt_asciiize">
<property name="text">
<string>&amp;Transliterate unicode characters to ASCII</string>
</property>
</widget>
</item>
<item row="10" column="0"> <item row="10" column="0">
<widget class="QCheckBox" name="opt_unsmarten_punctuation"> <widget class="QCheckBox" name="opt_unsmarten_punctuation">
<property name="text"> <property name="text">
@ -282,6 +263,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="1" colspan="2">
<widget class="QCheckBox" name="opt_keep_ligatures">
<property name="text">
<string>Keep &amp;ligatures</string>
</property>
</widget>
</item>
<item row="10" column="3"> <item row="10" column="3">
<widget class="QCheckBox" name="opt_linearize_tables"> <widget class="QCheckBox" name="opt_linearize_tables">
<property name="text"> <property name="text">
@ -289,6 +277,111 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="0" colspan="5">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="extra_css_tab">
<attribute name="title">
<string>&amp;Extra CSS</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTextEdit" name="opt_extra_css"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="opt_filter_css">
<attribute name="title">
<string>&amp;Filter Style Information</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" colspan="5">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Select what style information you want completely removed:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="filter_css_fonts">
<property name="toolTip">
<string>Removes the font-family CSS property</string>
</property>
<property name="text">
<string>&amp;Fonts</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="filter_css_margins">
<property name="toolTip">
<string>Removes the margin CSS properties. Note that page margins are not affected by this setting.</string>
</property>
<property name="text">
<string>&amp;Margins</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="filter_css_padding">
<property name="toolTip">
<string>Removes the padding CSS properties</string>
</property>
<property name="text">
<string>&amp;Padding</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QCheckBox" name="filter_css_floats">
<property name="toolTip">
<string>Convert floating images/text into static images/text</string>
</property>
<property name="text">
<string>F&amp;loats</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QCheckBox" name="filter_css_colors">
<property name="toolTip">
<string>Removes foreground and background colors</string>
</property>
<property name="text">
<string>&amp;Colors</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="5">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>&amp;Other CSS Properties:</string>
</property>
<property name="buddy">
<cstring>filter_css_others</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="filter_css_others">
<property name="toolTip">
<string>Comma separated list of CSS properties to remove. For example: display, color, font-family</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

View File

@ -131,8 +131,9 @@ def get_job_details(job):
def merge_result(oldmi, newmi, ensure_fields=None): def merge_result(oldmi, newmi, ensure_fields=None):
dummy = Metadata(_('Unknown')) dummy = Metadata(_('Unknown'))
for f in msprefs['ignore_fields']: for f in msprefs['ignore_fields']:
if ':' not in f and (ensure_fields and f not in ensure_fields): if ':' in f or (ensure_fields and f in ensure_fields):
setattr(newmi, f, getattr(dummy, f)) continue
setattr(newmi, f, getattr(dummy, f))
fields = set() fields = set()
for plugin in metadata_plugins(['identify']): for plugin in metadata_plugins(['identify']):
fields |= plugin.touched_fields fields |= plugin.touched_fields

View File

@ -127,7 +127,7 @@
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
<string>Number of conver download threads to use</string> <string>Number of cover download threads to use</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -5,8 +5,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: calibre 0.8.26\n" "Project-Id-Version: calibre 0.8.26\n"
"POT-Creation-Date: 2011-11-12 09:09+IST\n" "POT-Creation-Date: 2011-11-13 17:08+IST\n"
"PO-Revision-Date: 2011-11-12 09:09+IST\n" "PO-Revision-Date: 2011-11-13 17:08+IST\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"
@ -988,8 +988,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:102 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:102
#: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:447 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:447
#: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:470 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:470
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:529 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:532
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:548 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:551
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1048 #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1048
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1054 #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1054
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1089 #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1089
@ -2029,250 +2029,254 @@ msgstr ""
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:314 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:313
msgid "A comma separated list of CSS properties that will be removed from all CSS style rules. This is useful if the presence of some style information prevents it from being overridden on your device. For example: font-family,color,margin-left,margin-right"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:324
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:320 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:330
msgid "Some documents specify page margins by specifying a left and right margin on each individual paragraph. calibre will try to detect and remove these margins. Sometimes, this can cause the removal of margins that should not have been removed. In this case you can disable the removal." msgid "Some documents specify page margins by specifying a left and right margin on each individual paragraph. calibre will try to detect and remove these margins. Sometimes, this can cause the removal of margins that should not have been removed. In this case you can disable the removal."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:331
#, python-format
msgid "Set the top margin in pts. Default is %default. Note: 72 pts equals 1 inch"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:336
#, python-format
msgid "Set the bottom margin in pts. Default is %default. Note: 72 pts equals 1 inch"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:341 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:341
#, python-format #, python-format
msgid "Set the left 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:346 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:346
#, python-format #, python-format
msgid "Set the bottom margin in pts. Default is %default. Note: 72 pts equals 1 inch"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:351
#, python-format
msgid "Set the left margin in pts. Default is %default. Note: 72 pts equals 1 inch"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:356
#, python-format
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:352 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:362
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:362 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:372
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:369 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:379
msgid "When calibre removes blank lines between paragraphs, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent (in em). If you set this value negative, then the indent specified in the input document is used, that is, calibre does not change the indentation." msgid "When calibre removes blank lines between paragraphs, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent (in em). If you set this value negative, then the indent specified in the input document is used, that is, calibre does not change the indentation."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:378 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:388
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:384 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:394
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:391 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:401
msgid "Set the height of the inserted blank lines (in em). The height of the lines between paragraphs will be twice the value set here." msgid "Set the height of the inserted blank lines (in em). The height of the lines between paragraphs will be twice the value set here."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:398 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:408
msgid "Remove the first image from the input ebook. Useful if the input document has a cover image that is not identified as a cover. In this case, if you set a cover in calibre, the output document will end up with two cover images if you do not specify this option." msgid "Remove the first image from the input ebook. Useful if the input document has a cover image that is not identified as a cover. In this case, if you set a cover in calibre, the output document will end up with two cover images if you do not specify this option."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:407 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:417
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:415 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:425
msgid "Convert plain quotes, dashes and ellipsis to their typographically correct equivalents. For details, see http://daringfireball.net/projects/smartypants" msgid "Convert plain quotes, dashes and ellipsis to their typographically correct equivalents. For details, see http://daringfireball.net/projects/smartypants"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:423 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:433
msgid "Convert fancy quotes, dashes and ellipsis to their plain equivalents." msgid "Convert fancy quotes, dashes and ellipsis to their plain equivalents."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:431 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:441
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:438 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:448
#, python-format #, python-format
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 based on the current calibre interface language will be used." 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 based on the current calibre interface language will be used."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:453 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:463
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." 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 "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:465 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:475
#: /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:469 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:479
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:474 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:484
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:478 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:488
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:482 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:492
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:486 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:496
#: /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:490 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:500
#: /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:494 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:504
#: /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:498 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:508
#: /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:502 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:512
#: /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:506 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:516
#: /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:510 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:520
#: /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:514 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:524
#: /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:518 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:528
#: /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:522 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:532
msgid "Set the publication date." msgid "Set the publication date."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:526 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:536
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:530 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:540
msgid "Enable heuristic processing. This option must be set for any heuristic processing to take place." msgid "Enable heuristic processing. This option must be set for any heuristic processing to take place."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:535 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:545
msgid "Detect unformatted chapter headings and sub headings. Change them to h2 and h3 tags. This setting will not create a TOC, but can be used in conjunction with structure detection to create one." msgid "Detect unformatted chapter headings and sub headings. Change them to h2 and h3 tags. This setting will not create a TOC, but can be used in conjunction with structure detection to create one."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:542 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:552
msgid "Look for common words and patterns that denote italics and italicize them." msgid "Look for common words and patterns that denote italics and italicize them."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:547 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:557
msgid "Turn indentation created from multiple non-breaking space entities into CSS indents." msgid "Turn indentation created from multiple non-breaking space entities into CSS indents."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:552 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:562
msgid "Scale used to determine the length at which a line should be unwrapped. Valid values are a decimal between 0 and 1. The default is 0.4, just below the median line length. If only a few lines in the document require unwrapping this value should be reduced" msgid "Scale used to determine the length at which a line should be unwrapped. Valid values are a decimal between 0 and 1. The default is 0.4, just below the median line length. If only a few lines in the document require unwrapping this value should be reduced"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:560 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:570
msgid "Unwrap lines using punctuation and other formatting clues." msgid "Unwrap lines using punctuation and other formatting clues."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:564 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:574
msgid "Remove empty paragraphs from the document when they exist between every other paragraph" msgid "Remove empty paragraphs from the document when they exist between every other paragraph"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:569 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:579
msgid "Left aligned scene break markers are center aligned. Replace soft scene breaks that use multiple blank lines with horizontal rules." msgid "Left aligned scene break markers are center aligned. Replace soft scene breaks that use multiple blank lines with horizontal rules."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:575 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:585
msgid "Replace scene breaks with the specified text. By default, the text from the input document is used." msgid "Replace scene breaks with the specified text. By default, the text from the input document is used."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:580 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:590
msgid "Analyze hyphenated words throughout the document. The document itself is used as a dictionary to determine whether hyphens should be retained or removed." msgid "Analyze hyphenated words throughout the document. The document itself is used as a dictionary to determine whether hyphens should be retained or removed."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:586 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:596
msgid "Looks for occurrences of sequential <h1> or <h2> tags. The tags are renumbered to prevent splitting in the middle of chapter headings." msgid "Looks for occurrences of sequential <h1> or <h2> tags. The tags are renumbered to prevent splitting in the middle of chapter headings."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:592 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:602
msgid "Search pattern (regular expression) to be replaced with sr1-replace." msgid "Search pattern (regular expression) to be replaced with sr1-replace."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:597 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:607
msgid "Replacement to replace the text found with sr1-search." msgid "Replacement to replace the text found with sr1-search."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:601 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:611
msgid "Search pattern (regular expression) to be replaced with sr2-replace." msgid "Search pattern (regular expression) to be replaced with sr2-replace."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:606 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:616
msgid "Replacement to replace the text found with sr2-search." msgid "Replacement to replace the text found with sr2-search."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:610 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:620
msgid "Search pattern (regular expression) to be replaced with sr3-replace." msgid "Search pattern (regular expression) to be replaced with sr3-replace."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:615 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:625
msgid "Replacement to replace the text found with sr3-search." msgid "Replacement to replace the text found with sr3-search."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:719 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:729
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:777 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:787
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:784 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:794
msgid "Failed to parse date/time" msgid "Failed to parse date/time"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:943 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:953
msgid "Converting input to HTML..." msgid "Converting input to HTML..."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:970 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:980
msgid "Running transforms on ebook..." msgid "Running transforms on ebook..."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1074 #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1084
msgid "Creating" msgid "Creating"
msgstr "" msgstr ""
@ -5312,7 +5316,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/tweaks_ui.py:21 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/tweaks_ui.py:21
#: /home/kovid/work/calibre/src/calibre/gui2/store/basic_config_widget_ui.py:37 #: /home/kovid/work/calibre/src/calibre/gui2/store/basic_config_widget_ui.py:37
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:77 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:77
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:98 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:21
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:98 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:98
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email_ui.py:123 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email_ui.py:123
msgid "Form" msgid "Form"
@ -6017,15 +6021,15 @@ 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.py:35 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel.py:45
msgid "Original" msgid "Original"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel.py:36 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel.py:46
msgid "Left align" msgid "Left align"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel.py:37 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel.py:47
msgid "Justify text" msgid "Justify text"
msgstr "" msgstr ""
@ -6062,59 +6066,115 @@ msgid "Remove &spacing between paragraphs"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:97 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:97
msgid "Insert &blank line between paragraphs" msgid "&Indent size:"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:101 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:102
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:132
msgid " em"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:106
msgid "Text &justification:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:113
msgid "&Transliterate unicode characters to ASCII"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:117
msgid "Keep &ligatures"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:121
msgid "Extra &CSS"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:130
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:131 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:103
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:87 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:87
msgid "No change" msgid "No change"
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:104
msgid "&Indent size:" #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:120
msgid " em"
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:111
msgid "Insert &blank line between paragraphs"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:115
msgid "&Line size:" msgid "&Line size:"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:149 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:125
msgid "Text &justification:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:132
msgid "Smarten &punctuation" msgid "Smarten &punctuation"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:153 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:136
msgid "&Transliterate unicode characters to ASCII"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:140
msgid "&UnSmarten punctuation" msgid "&UnSmarten punctuation"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:157 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:144
msgid "Keep &ligatures"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:148
msgid "&Linearize tables" msgid "&Linearize tables"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:166
msgid "Select what style information you want completely removed:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:171
msgid "Removes the font-family CSS property"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:172
msgid "&Fonts"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:176
msgid "Removes the margin CSS properties. Note that page margins are not affected by this setting."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:177
msgid "&Margins"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:181
msgid "Removes the padding CSS properties"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:182
msgid "&Padding"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:186
msgid "Convert floating images/text into static images/text"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:187
msgid "F&loats"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:191
msgid "Removes foreground and background colors"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:192
msgid "&Colors"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:198
msgid "&Other CSS Properties:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:202
msgid "Comma separated list of CSS properties to remove. For example: display, color, font-family"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:227
msgid "&Extra CSS"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:228
msgid "&Filter Style Information"
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
msgid "LRF Output" msgid "LRF Output"
msgstr "" msgstr ""
@ -10652,7 +10712,7 @@ msgstr ""
msgid "(Failed cover)" msgid "(Failed cover)"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download.py:211 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download.py:212
#, python-format #, python-format
msgid "Downloaded %(num)d of %(tot)d" msgid "Downloaded %(num)d of %(tot)d"
msgstr "" msgstr ""
@ -13082,53 +13142,53 @@ msgstr ""
msgid "Configure..." msgid "Configure..."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:99 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:25
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:99 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:99
msgid "Time" msgid "Time"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:100 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:30
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:100 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:100
msgid "Number of seconds to wait for a store to respond" msgid "Number of seconds to wait for a store to respond"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:101 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:38
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:101 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:101
msgid "Number of seconds to let a store process results" msgid "Number of seconds to let a store process results"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:102 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:50
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:102 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:102
msgid "Display" msgid "Display"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:103 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:103 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:103
msgid "Maximum number of results to show per store" msgid "Maximum number of results to show per store"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:104 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:104 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:104
msgid "Open search result in system browser" msgid "Open search result in system browser"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:105 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:68
msgid "Threads" msgid "Threads"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:106 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:73
msgid "Number of search threads to use" msgid "Number of search threads to use"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:107 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:81
msgid "Number of cache update threads to use" msgid "Number of cache update threads to use"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:108 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:89
msgid "Number of conver download threads to use" msgid "Number of cover download threads to use"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:109 #: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:97
msgid "Number of details threads to use" msgid "Number of details threads to use"
msgstr "" msgstr ""