diff --git a/installer/windows/calibre/calibre.mpi b/installer/windows/calibre/calibre.mpi index 2b3cca3cae..ee7ab53455 100644 --- a/installer/windows/calibre/calibre.mpi +++ b/installer/windows/calibre/calibre.mpi @@ -299,7 +299,6 @@ File ::2BCD9281-2CBC-CF0D-0E12-2CE11F6ED758 -name comic2epub.exe.local -parent 8 File ::EDE6F457-C83F-C5FA-9AF4-38FDFF17D929 -name PIL._imagingtk.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::09D0906E-3611-3DB7-32CF-A140585694A7 -name win32pdh.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::4C84F0DC-7157-0C90-2062-180139B03E25 -name IM_MOD_RL_rgb_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 -File ::F402F507-87C5-BDB1-80AE-AD3FF4A4BCE7 -name bzrlib._patiencediff_c.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::A732EDE7-4796-241F-BECA-68E59F88F8AF -name lrs2lrf.exe -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::69072379-7D16-B9F7-9F39-3E6403C48267 -name IM_MOD_RL_xbm_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::FBD11D98-D1E7-5DD9-BF02-01CE92518859 -name IM_MOD_RL_otb_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 @@ -365,7 +364,6 @@ File ::26741B21-C241-E100-8BB1-8B679BC3E662 -name configure.xml -parent 8E5D85A4 File ::7D491E89-C6D3-1E6E-F4BD-8E55260FE33E -name libexpat.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::A4910EB3-0F1C-F6F0-CD2D-16A64BBAA92B -name calibre-fontconfig.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::8711327A-716D-B162-6AC6-2FB4AD071266 -name fb22lrf.exe -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 -File ::0FDD3A7A-31F3-8089-CE32-D80EAA6F62B2 -name bzrlib._btree_serializer_c.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::476CB977-5155-D56F-26CA-EB243AEBBA99 -name unrar.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::2DA1CC8D-AF5C-3B03-2060-301DFE0356CC -name mobi2oeb.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::2E2A9EDA-5386-444E-8479-557386794552 -name IM_MOD_RL_uil_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 @@ -487,7 +485,6 @@ File ::AA761ACD-B728-2324-AA75-B20A2A79F125 -name lrf2lrs.exe -parent 8E5D85A4-7 File ::95434C76-22F5-B9CE-6194-6E1B1EE3232D -name IM_MOD_RL_info_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::AAF45D03-322F-5553-63A7-312DB754A20B -name _ctypes.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::C3D351CA-A8D8-AB35-55D9-5AACF8DB37D1 -name python26.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 -File ::2F90B52F-A728-2CA4-5688-0283674695B7 -name _elementtree.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::B50B66A1-FB65-FAD5-1DD7-E894ACC07464 -name QtSvg4.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::906FF13D-D993-7192-7EA5-6D15A5A24BFB -name CORE_RL_png_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::5D368661-6BF0-D6AF-7C1A-87646864EB4B -name delegates.xml -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 @@ -552,7 +549,7 @@ SetupType ::D9ADE41C-B744-690C-2CED-CF826BF03D2E -setup Install -active Yes -pla InstallComponent 3EA07B17-04D8-6508-B535-96CC7173B49A -setup Install -type pane -conditions D7F585DB-0DEC-A94E-DAB0-94D558D82764 -title {Welcome Screen} -component Welcome -command insert -active Yes -parent StandardInstall Condition D7F585DB-0DEC-A94E-DAB0-94D558D82764 -active Yes -parent 3EA07B17-04D8-6508-B535-96CC7173B49A -title {Execute Script Condition} -component ExecuteScriptCondition -TreeObject::id D7F585DB-0DEC-A94E-DAB0-94D558D82764 -InstallComponent 7CCDA4BB-861C-C21E-3011-E93DB58F07D6 -setup Install -type action -conditions ADBCD53E-C9A6-A3CA-1AAC-0DB0CE84F71E -title {Check for Previous Install} -component CheckForPreviousInstall -command reorder -active Yes -parent 3EA07B17-04D8-6508-B535-96CC7173B49A +InstallComponent 7CCDA4BB-861C-C21E-3011-E93DB58F07D6 -setup Install -type action -conditions ADBCD53E-C9A6-A3CA-1AAC-0DB0CE84F71E -title {Check for Previous Install} -component CheckForPreviousInstall -command insert -active Yes -parent 3EA07B17-04D8-6508-B535-96CC7173B49A Condition ADBCD53E-C9A6-A3CA-1AAC-0DB0CE84F71E -active Yes -parent 7CCDA4BB-861C-C21E-3011-E93DB58F07D6 -title {Execute Script Condition} -component ExecuteScriptCondition -TreeObject::id ADBCD53E-C9A6-A3CA-1AAC-0DB0CE84F71E InstallComponent 580ACF2C-517F-5E48-9DEF-7DAEFBA59FDD -setup Install -type action -conditions 6DE3B369-9D6B-6BC1-4EA0-2C54ECE159EB -title {Set Virtual Text} -component SetVirtualText -command insert -active Yes -parent 3EA07B17-04D8-6508-B535-96CC7173B49A Condition 6DE3B369-9D6B-6BC1-4EA0-2C54ECE159EB -active Yes -parent 580ACF2C-517F-5E48-9DEF-7DAEFBA59FDD -title {String Is Condition} -component StringIsCondition -TreeObject::id 6DE3B369-9D6B-6BC1-4EA0-2C54ECE159EB diff --git a/installer/windows/freeze.py b/installer/windows/freeze.py index 064615f422..ab58fb669d 100644 --- a/installer/windows/freeze.py +++ b/installer/windows/freeze.py @@ -12,7 +12,7 @@ LIBUNRAR = 'C:\\Program Files\\UnrarDLL\\unrar.dll' PDFTOHTML = 'C:\\pdftohtml\\pdftohtml.exe' IMAGEMAGICK_DIR = 'C:\\ImageMagick' FONTCONFIG_DIR = 'C:\\fontconfig' -VC90 = r'C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT' +VC90 = r'C:\VC90.CRT' import sys, os, py2exe, shutil, zipfile, glob, subprocess, re from distutils.core import setup diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 0828c15b98..7315deca40 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -17,10 +17,17 @@ from calibre.constants import iswindows, isosx, islinux, isfrozen, \ filesystem_encoding import mechanize -mimetypes.add_type('application/epub+zip', '.epub') -mimetypes.add_type('text/x-sony-bbeb+xml', '.lrs') -mimetypes.add_type('application/x-sony-bbeb', '.lrf') -mimetypes.add_type('application/x-dtbncx+xml', '.ncx') +mimetypes.add_type('application/epub+zip', '.epub') +mimetypes.add_type('text/x-sony-bbeb+xml', '.lrs') +mimetypes.add_type('http://www.w3.org/1999/xhtml', '.xhtml') +mimetypes.add_type('image/svg+xml', '.svg') +mimetypes.add_type('application/x-sony-bbeb', '.lrf') +mimetypes.add_type('application/x-dtbncx+xml', '.ncx') +mimetypes.add_type('application/adobe-page-template+xml', '.xpgt') +mimetypes.add_type('application/x-font-opentype', '.otf') +mimetypes.add_type('application/x-font-truetype', '.ttf') +mimetypes.add_type('application/oebps-package+xml', '.opf') + def to_unicode(raw, encoding='utf-8', errors='strict'): if isinstance(raw, unicode): diff --git a/src/calibre/constants.py b/src/calibre/constants.py index b92fb0f0e1..fac71aa8da 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -2,7 +2,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __appname__ = 'calibre' -__version__ = '0.4.132' +__version__ = '0.4.134' __author__ = "Kovid Goyal " ''' Various run time constants. diff --git a/src/calibre/devices/prs500/driver.py b/src/calibre/devices/prs500/driver.py index cca71376d4..2f1caaee9d 100755 --- a/src/calibre/devices/prs500/driver.py +++ b/src/calibre/devices/prs500/driver.py @@ -96,7 +96,7 @@ class PRS500(Device): # Location of cache.xml on storage card in device CACHE_XML = "/Sony Reader/database/cache.xml" # Ordered list of supported formats - FORMATS = ["lrf", "rtf", "pdf", "txt"] + FORMATS = ["lrf", "lrx", "rtf", "pdf", "txt"] # Height for thumbnails of books/images on the device THUMBNAIL_HEIGHT = 68 # Directory on card to which books are copied diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index bbda8f95d2..9308af2c5a 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -27,12 +27,12 @@ class File(object): class PRS505(Device): - VENDOR_ID = 0x054c #: SONY Vendor Id - PRODUCT_ID = 0x031e #: Product Id for the PRS-505 + VENDOR_ID = 0x054c #: SONY Vendor Id + PRODUCT_ID = 0x031e #: Product Id for the PRS-505 BCD = [0x229] #: Needed to disambiguate 505 and 700 on linux PRODUCT_NAME = 'PRS-505' VENDOR_NAME = 'SONY' - FORMATS = ['lrf', 'epub', "rtf", "pdf", "txt"] + FORMATS = ['lrf', 'epub', 'lrx', 'rtf', 'pdf', 'txt'] MEDIA_XML = 'database/cache/media.xml' CACHE_XML = 'Sony Reader/database/cache.xml' @@ -147,6 +147,7 @@ class PRS505(Device): def open_windows(self): + time.sleep(6) drives = [] wmi = __import__('wmi', globals(), locals(), [], -1) c = wmi.WMI() diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index a33d041b2a..761fe9ba74 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -172,6 +172,7 @@ class Device(_Device): return prefix def open_windows(self): + time.sleep(6) drives = {} wmi = __import__('wmi', globals(), locals(), [], -1) c = wmi.WMI() diff --git a/src/calibre/ebooks/epub/__init__.py b/src/calibre/ebooks/epub/__init__.py index 1bbb80cf13..aa17024d50 100644 --- a/src/calibre/ebooks/epub/__init__.py +++ b/src/calibre/ebooks/epub/__init__.py @@ -102,13 +102,23 @@ def config(defaults=None, name='epub'): c.remove_opt('zip') c.add_opt('output', ['-o', '--output'], default=None, - help=_('The output EPUB file. If not specified, it is derived from the input file name.')) + help=_('The output EPUB file. If not specified, it is ' + 'derived from the input file name.')) c.add_opt('profile', ['--profile'], default='PRS505', choices=list(PROFILES.keys()), - help=_('Profile of the target device this EPUB is meant for. Set to None to create a device independent EPUB. The profile is used for device specific restrictions on the EPUB. Choices are: ')+str(list(PROFILES.keys()))) + help=_('Profile of the target device this EPUB is meant for. ' + 'Set to None to create a device independent EPUB. ' + 'The profile is used for device specific restrictions ' + 'on the EPUB. Choices are: ')+str(list(PROFILES.keys()))) c.add_opt('override_css', ['--override-css'], default=None, - help=_('Either the path to a CSS stylesheet or raw CSS. This CSS will override any existing CSS declarations in the source files.')) - structure = c.add_group('structure detection', _('Control auto-detection of document structure.')) - structure('chapter', ['--chapter'], default="//*[re:match(name(), 'h[1-2]') and re:test(., 'chapter|book|section|part', 'i')] | //*[@class = 'chapter']", + help=_('Either the path to a CSS stylesheet or raw CSS. ' + 'This CSS will override any existing CSS ' + 'declarations in the source files.')) + structure = c.add_group('structure detection', + _('Control auto-detection of document structure.')) + structure('chapter', ['--chapter'], + default="//*[re:match(name(), 'h[1-2]') and " + "re:test(., 'chapter|book|section|part', 'i')] | " + "//*[@class = 'chapter']", help=_('''\ An XPath expression to detect chapter titles. The default is to consider

or

tags that contain the words "chapter","book","section" or "part" as chapter titles as @@ -118,14 +128,39 @@ use the expression "/". See the XPath Tutorial in the calibre User Manual for fu help on using this feature. ''').replace('\n', ' ')) structure('chapter_mark', ['--chapter-mark'], choices=['pagebreak', 'rule', 'both', 'none'], - default='pagebreak', help=_('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.')) + default='pagebreak', + help=_('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.')) structure('cover', ['--cover'], default=None, help=_('Path to the cover to be used for this book')) structure('prefer_metadata_cover', ['--prefer-metadata-cover'], default=False, action='store_true', - help=_('Use the cover detected from the source file in preference to the specified cover.')) + help=_('Use the cover detected from the source file in preference ' + 'to the specified cover.')) + structure('remove_first_image', ['--remove-first-image'], default=False, + help=_('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.')) structure('dont_split_on_page_breaks', ['--dont-split-on-page-breaks'], default=False, - help=_('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.')) + help=_('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.')) + structure('page', ['--page'], default=None, + help=_('XPath expression to detect page boundaries for building ' + 'a custom pagination map, as used by AdobeDE. Default is ' + 'not to build an explicit pagination map.')) + structure('page_names', ['--page-names'], default=None, + help=_('XPath expression to find the name of each page in the ' + 'pagination map relative to its boundary element. ' + 'Default is to number all pages staring with 1.')) toc = c.add_group('toc', _('''\ Control the automatic generation of a Table of Contents. If an OPF file is detected @@ -133,21 +168,36 @@ and it specifies a Table of Contents, then that will be used rather than trying to auto-generate a Table of Contents. ''').replace('\n', ' ')) toc('max_toc_links', ['--max-toc-links'], default=50, - help=_('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 --toc-threshold number of chapters were detected.')) + help=_('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 --toc-threshold number of chapters were detected.')) toc('no_chapters_in_toc', ['--no-chapters-in-toc'], default=False, help=_("Don't add auto-detected chapters to the Table of Contents.")) toc('toc_threshold', ['--toc-threshold'], default=6, - help=_('If fewer than this number of chapters is detected, then links are added to the Table of Contents. Default: %default')) + help=_('If fewer than this number of chapters is detected, then links ' + 'are added to the Table of Contents. Default: %default')) toc('level1_toc', ['--level1-toc'], default=None, - help=_('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.')) + help=_('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.')) toc('level2_toc', ['--level2-toc'], default=None, - help=_('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.')) + help=_('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.')) toc('level3_toc', ['--level3-toc'], default=None, - help=_('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.')) + help=_('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.')) toc('from_ncx', ['--from-ncx'], default=None, - help=_('Path to a .ncx file that contains the table of contents to use for this ebook. The NCX file should contain links relative to the directory it is placed in. See http://www.niso.org/workrooms/daisy/Z39-86-2005.html#NCX for an overview of the NCX format.')) + help=_('Path to a .ncx file that contains the table of contents to use ' + 'for this ebook. The NCX file should contain links relative to ' + 'the directory it is placed in. See ' + 'http://www.niso.org/workrooms/daisy/Z39-86-2005.html#NCX for ' + 'an overview of the NCX format.')) toc('use_auto_toc', ['--use-auto-toc'], default=False, - help=_('Normally, if the source file already has a Table of Contents, it is used in preference to the autodetected one. With this option, the autodetected one is always used.')) + help=_('Normally, if the source file already has a Table of Contents, ' + 'it is used in preference to the autodetected one. ' + 'With this option, the autodetected one is always used.')) layout = c.add_group('page layout', _('Control page layout')) layout('margin_top', ['--margin-top'], default=5.0, @@ -159,18 +209,33 @@ to auto-generate a Table of Contents. layout('margin_right', ['--margin-right'], default=5.0, help=_('Set the right margin in pts. Default is %default')) layout('base_font_size2', ['--base-font-size'], default=12.0, - help=_('The base font size in pts. Default is %defaultpt. Set to 0 to disable rescaling of fonts.')) + help=_('The base font size in pts. Default is %defaultpt. ' + 'Set to 0 to disable rescaling of fonts.')) layout('remove_paragraph_spacing', ['--remove-paragraph-spacing'], default=False, - help=_('Remove spacing between paragraphs. Will not work if the source file forces inter-paragraph spacing.')) + help=_('Remove spacing between paragraphs. ' + 'Also sets a indent on paragraphs of 1.5em. ' + 'You can override this by adding p {text-indent: 0cm} to ' + '--override-css. Spacing removal will not work if the source ' + 'file forces inter-paragraph spacing.')) + layout('no_justification', ['--no-justification'], default=False, + help=_('Do not force text to be justified in output.')) + layout('linearize_tables', ['--linearize-tables'], default=False, + help=_('Remove table markup, converting it into paragraphs. ' + 'This is useful if your source file uses a table to manage layout.')) layout('preserve_tag_structure', ['--preserve-tag-structure'], default=False, - help=_('Preserve the HTML tag structure while splitting large HTML files. This is only neccessary if the HTML files contain CSS that uses sibling selectors. Enabling this greatly slows down processing of large HTML files.')) + help=_('Preserve the HTML tag structure while splitting large HTML files. ' + 'This is only neccessary if the HTML files contain CSS that ' + 'uses sibling selectors. Enabling this greatly slows down ' + 'processing of large HTML files.')) c.add_opt('show_opf', ['--show-opf'], default=False, group='debug', help=_('Print generated OPF file to stdout')) c.add_opt('show_ncx', ['--show-ncx'], default=False, group='debug', help=_('Print generated NCX file to stdout')) - c.add_opt('keep_intermediate', ['--keep-intermediate-files'], group='debug', default=False, + c.add_opt('keep_intermediate', ['--keep-intermediate-files'], group='debug', + default=False, help=_('Keep intermediate files during processing by html2epub')) c.add_opt('extract_to', ['--extract-to'], group='debug', default=None, - help=_('Extract the contents of the produced EPUB file to the specified directory.')) - return c \ No newline at end of file + help=_('Extract the contents of the produced EPUB file to the ' + 'specified directory.')) + return c diff --git a/src/calibre/ebooks/epub/from_html.py b/src/calibre/ebooks/epub/from_html.py index 30191617a5..bd9b59cfbd 100644 --- a/src/calibre/ebooks/epub/from_html.py +++ b/src/calibre/ebooks/epub/from_html.py @@ -46,6 +46,7 @@ from calibre.ebooks.metadata.toc import TOC from calibre.ebooks.metadata.opf2 import OPF from calibre.ebooks.epub import initialize_container, PROFILES from calibre.ebooks.epub.split import split +from calibre.ebooks.epub.pages import add_page_map from calibre.ebooks.epub.fonts import Rationalizer from calibre.constants import preferred_encoding from calibre.customize.ui import run_plugins_on_postprocess @@ -141,7 +142,7 @@ class HTMLProcessor(Processor, Rationalizer): p = QPixmap() p.load(path) if not p.isNull(): - p.save(path+'_calibre_converted.jpg') + p.save(path + '_calibre_converted.jpg') os.remove(path) for key, val in self.resource_map.items(): if val == rpath: @@ -194,7 +195,10 @@ class HTMLProcessor(Processor, Rationalizer): if not tag.text and not tag.get('src', False): tag.getparent().remove(tag) - + if self.opts.linearize_tables: + for tag in self.root.xpath('//table | //tr | //th | //td'): + tag.tag = 'div' + def save(self): for meta in list(self.root.xpath('//meta')): @@ -203,6 +207,13 @@ class HTMLProcessor(Processor, Rationalizer): # self.convert_image(img) Processor.save(self) + def remove_first_image(self): + images = self.root.xpath('//img') + if images: + images[0].getparent().remove(images[0]) + return True + return False + @@ -224,10 +235,13 @@ def parse_content(filelist, opts, tdir): resource_map, stylesheets = {}, {} toc = TOC(base_path=tdir, type='root') stylesheet_map = {} + first_image_removed = False for htmlfile in filelist: logging.getLogger('html2epub').debug('Processing %s...'%htmlfile) hp = HTMLProcessor(htmlfile, opts, os.path.join(tdir, 'content'), resource_map, filelist, stylesheets) + if not first_image_removed and opts.remove_first_image: + first_image_removed = hp.remove_first_image() hp.populate_toc(toc) hp.save() stylesheet_map[os.path.basename(hp.save_path())] = \ @@ -425,6 +439,9 @@ def convert(htmlfile, opts, notification=None, create_epub=True, if opts.show_ncx: print toc split(opf_path, opts, stylesheet_map) + if opts.page: + logger.info('\tBuilding page map...') + add_page_map(opf_path, opts) check_links(opf_path, opts.pretty_print) opf = OPF(opf_path, tdir) @@ -441,12 +458,9 @@ def convert(htmlfile, opts, notification=None, create_epub=True, cpath = os.path.join(tdir, 'content', 'resources', '_cover_.jpg') if os.path.exists(cpath): - opf.add_path_to_manifest(cpath, 'image/jpeg') + opf.add_path_to_manifest(cpath, 'image/jpeg') with open(opf_path, 'wb') as f: - raw = opf.render() - if not raw.startswith('\n'+raw - f.write(raw) + f.write(opf.render()) ncx_path = os.path.join(os.path.dirname(opf_path), 'toc.ncx') if os.path.exists(ncx_path) and os.stat(ncx_path).st_size > opts.profile.flow_size: logger.info('Condensing NCX from %d bytes...'%os.stat(ncx_path).st_size) @@ -462,7 +476,7 @@ def convert(htmlfile, opts, notification=None, create_epub=True, logger.info(_('Output written to ')+opts.output) if opts.show_opf: - print open(os.path.join(tdir, 'metadata.opf')).read() + print open(opf_path, 'rb').read() if opts.extract_to is not None: if os.path.exists(opts.extract_to): diff --git a/src/calibre/ebooks/epub/pages.py b/src/calibre/ebooks/epub/pages.py new file mode 100644 index 0000000000..1ab5edde86 --- /dev/null +++ b/src/calibre/ebooks/epub/pages.py @@ -0,0 +1,59 @@ +''' +Add page mapping information to an EPUB book. +''' + +from __future__ import with_statement + +__license__ = 'GPL v3' +__copyright__ = '2008, Marshall T. Vandegrift ' +__docformat__ = 'restructuredtext en' + +import os, re +from itertools import count, chain +from calibre.ebooks.oeb.base import XHTML, XHTML_NS +from calibre.ebooks.oeb.base import OEBBook, DirWriter +from lxml import etree, html +from lxml.etree import XPath + +NSMAP = {'h': XHTML_NS, 'html': XHTML_NS, 'xhtml': XHTML_NS} +PAGE_RE = re.compile(r'page', re.IGNORECASE) +ROMAN_RE = re.compile(r'^[ivxlcdm]+$', re.IGNORECASE) + +def filter_name(name): + name = name.strip() + name = PAGE_RE.sub('', name) + for word in name.split(): + if word.isdigit() or ROMAN_RE.match(word): + name = word + break + return name + +def build_name_for(expr): + if not expr: + counter = count(1) + return lambda elem: str(counter.next()) + selector = XPath(expr, namespaces=NSMAP) + def name_for(elem): + results = selector(elem) + if not results: + return '' + name = ' '.join(results) + return filter_name(name) + return name_for + +def add_page_map(opfpath, opts): + oeb = OEBBook(opfpath) + selector = XPath(opts.page, namespaces=NSMAP) + name_for = build_name_for(opts.page_names) + idgen = ("calibre-page-%d" % n for n in count(1)) + for item in oeb.spine: + data = item.data + for elem in selector(data): + name = name_for(elem) + id = elem.get('id', None) + if id is None: + id = elem.attrib['id'] = idgen.next() + href = '#'.join((item.href, id)) + oeb.pages.add(name, href) + writer = DirWriter(version='2.0', page_map=True) + writer.dump(oeb, opfpath) diff --git a/src/calibre/ebooks/html.py b/src/calibre/ebooks/html.py index a7883ed763..9a273c42ce 100644 --- a/src/calibre/ebooks/html.py +++ b/src/calibre/ebooks/html.py @@ -9,7 +9,7 @@ directory or zip file. All the action starts in :function:`create_dir`. ''' import sys, re, os, shutil, logging, tempfile, cStringIO, operator, functools -from urlparse import urlparse +from urlparse import urlparse, urlunparse from urllib import unquote from lxml import etree @@ -98,7 +98,8 @@ class Link(object): @classmethod def url_to_local_path(cls, url, base): - path = url.path + path = urlunparse(('', '', url.path, url.params, url.query, '')) + path = unquote(path) if os.path.isabs(path): return path return os.path.abspath(os.path.join(base, path)) @@ -111,11 +112,11 @@ class Link(object): ''' assert isinstance(url, unicode) and isinstance(base, unicode) self.url = url - self.parsed_url = urlparse(unquote(self.url)) + self.parsed_url = urlparse(self.url) self.is_local = self.parsed_url.scheme in ('', 'file') self.is_internal = self.is_local and not bool(self.parsed_url.path) self.path = None - self.fragment = self.parsed_url.fragment + self.fragment = unquote(self.parsed_url.fragment) if self.is_local and not self.is_internal: self.path = self.url_to_local_path(self.parsed_url, base) @@ -594,15 +595,21 @@ class Processor(Parser): ''' Populate the Table of Contents from detected chapters and links. ''' - - def add_item(href, fragment, text, target, type='link'): - for entry in toc.flat(): - if entry.href == href and entry.fragment == fragment: - return entry - if len(text) > 50: - text = text[:50] + u'\u2026' - return target.add_item(href, fragment, text, type=type) - + class Adder(object): + + def __init__(self, toc): + self.next_play_order = max([x.play_order for x in toc.flat()]) + + def __call__(self, href, fragment, text, target, type='link'): + for entry in toc.flat(): + if entry.href == href and entry.fragment == fragment: + return entry + if len(text) > 50: + text = text[:50] + u'\u2026' + self.next_play_order += 1 + return target.add_item(href, fragment, text, type=type, + play_order=self.next_play_order) + add_item = Adder(toc) name = self.htmlfile_map[self.htmlfile.path] href = 'content/'+name @@ -629,13 +636,15 @@ class Processor(Parser): if self.opts.level1_toc is not None: level1 = self.opts.level1_toc(self.root) + level1_order = [] if level1: added = {} for elem in level1: text, _href, frag = elem_to_link(elem, href, counter) counter += 1 if text: - added[elem] = add_item(_href, frag, text, toc, type='chapter') + level1_order.append(add_item(_href, frag, text, toc, type='chapter')) + added[elem] = level1_order[-1] add_item(_href, frag, 'Top', added[elem], type='chapter') if self.opts.level2_toc is not None: added2 = {} @@ -664,6 +673,15 @@ class Processor(Parser): if text: add_item(_href, frag, text, level2, type='chapter') + + if level1_order: # Fix play order + next_play_order = level1_order[0].play_order + for x in level1_order: + for y in x.flat(): + y.play_order = next_play_order + next_play_order += 1 + + if len(toc) > 0: return @@ -867,6 +885,8 @@ class Processor(Parser): css += '\n\na { color: inherit; text-decoration: inherit; cursor: default; }\na[href] { color: blue; text-decoration: underline; cursor:pointer; }' if self.opts.remove_paragraph_spacing: css += '\n\np {text-indent: 1.5em; margin-top:0pt; margin-bottom:0pt; padding:0pt; border:0pt;}' + if not self.opts.no_justification: + css += '\n\nbody {text-align: justify}' if self.opts.override_css: css += '\n\n' + self.opts.override_css self.override_css = self.css_parser.parseString(self.preprocess_css(css)) @@ -987,7 +1007,6 @@ def merge_metadata(htmlfile, opf, opts): mi = get_metadata(open(htmlfile, 'rb'), 'html') except: mi = MetaInformation(None, None) - if opts.from_opf is not None and os.access(opts.from_opf, os.R_OK): mi.smart_update(OPF(open(opts.from_opf, 'rb'), os.path.abspath(os.path.dirname(opts.from_opf)))) for attr in ('title', 'authors', 'publisher', 'tags', 'comments'): diff --git a/src/calibre/ebooks/lit/writer.py b/src/calibre/ebooks/lit/writer.py index 5026c9e267..4a059b6433 100644 --- a/src/calibre/ebooks/lit/writer.py +++ b/src/calibre/ebooks/lit/writer.py @@ -23,7 +23,7 @@ from urllib import unquote as urlunquote from lxml import etree from calibre.ebooks.lit.reader import DirectoryEntry import calibre.ebooks.lit.maps as maps -from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES, OEB_CSS_MIME, \ +from calibre.ebooks.oeb.base import OEB_DOCS, XHTML_MIME, OEB_STYLES, \ CSS_MIME, OPF_MIME, XML_NS, XML from calibre.ebooks.oeb.base import namespace, barename, prefixname, \ urlnormalize, xpath @@ -474,7 +474,7 @@ class LitWriter(object): name = '/data/' + item.id data = item.data secnum = 0 - if not isinstance(data, basestring): + if isinstance(data, etree._Element): self._add_folder(name) rebin = ReBinary(data, item, self._oeb, map=HTML_MAP) self._add_file(name + '/ahc', rebin.ahc, 0) @@ -483,6 +483,8 @@ class LitWriter(object): data = rebin.content name = name + '/content' secnum = 1 + elif isinstance(data, unicode): + data = data.encode('utf-8') self._add_file(name, data, secnum) item.size = len(data) @@ -493,7 +495,7 @@ class LitWriter(object): if item.spine_position is not None: key = 'linear' if item.linear else 'nonlinear' manifest[key].append(item) - elif item.media_type == CSS_MIME: + elif item.media_type in OEB_STYLES: manifest['css'].append(item) elif item.media_type in LIT_IMAGES: manifest['images'].append(item) @@ -506,6 +508,11 @@ class LitWriter(object): data.write(pack('%s%s'%x diff --git a/src/calibre/ebooks/metadata/opf.xml b/src/calibre/ebooks/metadata/opf.xml index d95268f306..94a8f63b3c 100644 --- a/src/calibre/ebooks/metadata/opf.xml +++ b/src/calibre/ebooks/metadata/opf.xml @@ -6,9 +6,9 @@ > - ${mi.title} + ${mi.title} ${author} - ${'%s (%s)'%(__appname__, __version__)} [http://${__appname__}.kovidgoyal.net] + ${'%s (%s)'%(__appname__, __version__)} [http://${__appname__}.kovidgoyal.net] ${mi.application_id} ${mi.language if mi.language else 'UND'} diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index f7282abfcd..2e6fe598ec 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -17,21 +17,21 @@ from calibre.ebooks.chardet import xml_to_unicode from calibre import relpath from calibre.constants import __appname__, __version__ from calibre.ebooks.metadata.toc import TOC -from calibre.ebooks.metadata import MetaInformation, get_parser +from calibre.ebooks.metadata import MetaInformation class Resource(object): ''' - Represents a resource (usually a file on the filesystem or a URL pointing + Represents a resource (usually a file on the filesystem or a URL pointing to the web. Such resources are commonly referred to in OPF files. - + They have the interface: - + :member:`path` :member:`mime_type` :method:`href` ''' - + def __init__(self, href_or_path, basedir=os.getcwd(), is_path=True): self.orig = href_or_path self._href = None @@ -63,13 +63,13 @@ class Resource(object): pc = pc.decode('utf-8') self.path = os.path.abspath(os.path.join(basedir, pc.replace('/', os.sep))) self.fragment = url[-1] - - + + def href(self, basedir=None): ''' Return a URL pointing to this resource. If it is a file on the filesystem the URL is relative to `basedir`. - + `basedir`: If None, the basedir of this resource is used (see :method:`set_basedir`). If this resource has no basedir, then the current working directory is used as the basedir. ''' @@ -91,54 +91,54 @@ class Resource(object): if isinstance(rpath, unicode): rpath = rpath.encode('utf-8') return rpath.replace(os.sep, '/')+frag - + def set_basedir(self, path): self._basedir = path - + def basedir(self): return self._basedir - + def __repr__(self): return 'Resource(%s, %s)'%(repr(self.path), repr(self.href())) - - + + class ResourceCollection(object): - + def __init__(self): self._resources = [] - + def __iter__(self): for r in self._resources: yield r - + def __len__(self): return len(self._resources) - + def __getitem__(self, index): return self._resources[index] - + def __bool__(self): return len(self._resources) > 0 - + def __str__(self): resources = map(repr, self) return '[%s]'%', '.join(resources) - + def __repr__(self): return str(self) - + def append(self, resource): if not isinstance(resource, Resource): raise ValueError('Can only append objects of type Resource') self._resources.append(resource) - + def remove(self, resource): self._resources.remove(resource) - + def replace(self, start, end, items): 'Same as list[start:end] = items' self._resources[start:end] = items - + @staticmethod def from_directory_contents(top, topdown=True): collection = ResourceCollection() @@ -148,16 +148,16 @@ class ResourceCollection(object): res.set_basedir(top) collection.append(res) return collection - + def set_basedir(self, path): for res in self: res.set_basedir(path) - + class ManifestItem(Resource): - + @staticmethod def from_opf_manifest_item(item, basedir): href = item.get('href', None) @@ -167,7 +167,7 @@ class ManifestItem(Resource): if mt: res.mime_type = mt return res - + @apply def media_type(): def fget(self): @@ -175,18 +175,18 @@ class ManifestItem(Resource): def fset(self, val): self.mime_type = val return property(fget=fget, fset=fset) - - + + def __unicode__(self): return u''%(self.id, self.href(), self.media_type) - + def __str__(self): return unicode(self).encode('utf-8') - + def __repr__(self): return unicode(self) - - + + def __getitem__(self, index): if index == 0: return self.href() @@ -196,7 +196,7 @@ class ManifestItem(Resource): class Manifest(ResourceCollection): - + @staticmethod def from_opf_manifest_element(items, dir): m = Manifest() @@ -211,7 +211,7 @@ class Manifest(ResourceCollection): except ValueError: continue return m - + @staticmethod def from_paths(entries): ''' @@ -226,7 +226,7 @@ class Manifest(ResourceCollection): m.next_id += 1 m.append(mi) return m - + def add_item(self, path, mime_type=None): mi = ManifestItem(path, is_path=True) if mime_type: @@ -235,37 +235,37 @@ class Manifest(ResourceCollection): self.next_id += 1 self.append(mi) return mi.id - + def __init__(self): ResourceCollection.__init__(self) self.next_id = 1 - - + + def item(self, id): for i in self: if i.id == id: return i - + def id_for_path(self, path): path = os.path.normpath(os.path.abspath(path)) for i in self: if i.path and os.path.normpath(i.path) == path: - return i.id - + return i.id + def path_for_id(self, id): for i in self: if i.id == id: return i.path class Spine(ResourceCollection): - + class Item(Resource): - + def __init__(self, idfunc, *args, **kwargs): Resource.__init__(self, *args, **kwargs) self.is_linear = True self.id = idfunc(self.path) - + @staticmethod def from_opf_spine_element(itemrefs, manifest): s = Spine(manifest) @@ -278,7 +278,7 @@ class Spine(ResourceCollection): r.is_linear = itemref.get('linear', 'yes') == 'yes' s.append(r) return s - + @staticmethod def from_paths(paths, manifest): s = Spine(manifest) @@ -288,14 +288,14 @@ class Spine(ResourceCollection): except: continue return s - - - + + + def __init__(self, manifest): ResourceCollection.__init__(self) self.manifest = manifest - - + + def replace(self, start, end, ids): ''' Replace the items between start (inclusive) and end (not inclusive) with @@ -308,7 +308,7 @@ class Spine(ResourceCollection): raise ValueError('id %s not in manifest') items.append(Spine.Item(lambda x: id, path, is_path=True)) ResourceCollection.replace(start, end, items) - + def linear_items(self): for r in self: if r.is_linear: @@ -318,15 +318,15 @@ class Spine(ResourceCollection): for r in self: if not r.is_linear: yield r.path - + def items(self): for i in self: yield i.path - + class Guide(ResourceCollection): - + class Reference(Resource): - + @staticmethod def from_opf_resource_item(ref, basedir): title, href, type = ref.get('title', ''), ref.get('href'), ref.get('type') @@ -334,14 +334,14 @@ class Guide(ResourceCollection): res.title = title res.type = type return res - + def __repr__(self): ans = '' - - + + @staticmethod def from_opf_guide(references, base_dir=os.getcwdu()): coll = Guide() @@ -352,7 +352,7 @@ class Guide(ResourceCollection): except: continue return coll - + def set_cover(self, path): map(self.remove, [i for i in self if 'cover' in i.type.lower()]) for type in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'): @@ -362,13 +362,13 @@ class Guide(ResourceCollection): class MetadataField(object): - + def __init__(self, name, is_dc=True, formatter=None, none_is=None): self.name = name self.is_dc = is_dc self.formatter = formatter self.none_is = none_is - + def __real_get__(self, obj, type=None): ans = obj.get_metadata_element(self.name) if ans is None: @@ -382,13 +382,13 @@ class MetadataField(object): except: return None return ans - + def __get__(self, obj, type=None): ans = self.__real_get__(obj, type) if ans is None: ans = self.none_is return ans - + def __set__(self, obj, val): elem = obj.get_metadata_element(self.name) if elem is None: @@ -410,10 +410,11 @@ class OPF(object): XPath = functools.partial(etree.XPath, namespaces=xpn) CONTENT = XPath('self::*[re:match(name(), "meta$", "i")]/@content') TEXT = XPath('string()') - - + + metadata_path = XPath('descendant::*[re:match(name(), "metadata", "i")]') metadata_elem_path = XPath('descendant::*[re:match(name(), concat($name, "$"), "i") or (re:match(name(), "meta$", "i") and re:match(@name, concat("^calibre:", $name, "$"), "i"))]') + title_path = XPath('descendant::*[re:match(name(), "title", "i")]') authors_path = XPath('descendant::*[re:match(name(), "creator", "i") and (@role="aut" or @opf:role="aut" or (not(@role) and not(@opf:role)))]') bkp_path = XPath('descendant::*[re:match(name(), "contributor", "i") and (@role="bkp" or @opf:role="bkp")]') tags_path = XPath('descendant::*[re:match(name(), "subject", "i")]') @@ -423,10 +424,10 @@ class OPF(object): application_id_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '+ '(re:match(@opf:scheme, "calibre|libprs500", "i") or re:match(@scheme, "calibre|libprs500", "i"))]') manifest_path = XPath('descendant::*[re:match(name(), "manifest", "i")]/*[re:match(name(), "item", "i")]') - manifest_ppath = XPath('descendant::*[re:match(name(), "manifest", "i")]') + manifest_ppath = XPath('descendant::*[re:match(name(), "manifest", "i")]') spine_path = XPath('descendant::*[re:match(name(), "spine", "i")]/*[re:match(name(), "itemref", "i")]') guide_path = XPath('descendant::*[re:match(name(), "guide", "i")]/*[re:match(name(), "reference", "i")]') - + title = MetadataField('title') publisher = MetadataField('publisher') language = MetadataField('language') @@ -435,8 +436,8 @@ class OPF(object): series = MetadataField('series', is_dc=False) series_index = MetadataField('series_index', is_dc=False, formatter=int, none_is=1) rating = MetadataField('rating', is_dc=False, formatter=int) - - + + def __init__(self, stream, basedir=os.getcwdu(), unquote_urls=True): if not hasattr(stream, 'read'): stream = open(stream, 'rb') @@ -463,7 +464,7 @@ class OPF(object): self.guide = Guide.from_opf_guide(guide, basedir) if guide else None self.cover_data = (None, None) self.find_toc() - + def find_toc(self): self.toc = None try: @@ -480,7 +481,7 @@ class OPF(object): for item in self.manifest: if 'toc' in item.href().lower(): toc = item.path - + if toc is None: return self.toc = TOC(base_path=self.base_dir) if toc.lower() in ('ncx', 'ncxtoc'): @@ -494,22 +495,22 @@ class OPF(object): else: self.toc.read_html_toc(toc) except: - pass - - - + pass + + + def get_text(self, elem): return u''.join(self.CONTENT(elem) or self.TEXT(elem)) def set_text(self, elem, content): if elem.tag == self.META: - elem.attib['content'] = content + elem.attrib['content'] = content else: elem.text = content - + def itermanifest(self): return self.manifest_path(self.root) - + def create_manifest_item(self, href, media_type): ids = [i.get('id', None) for i in self.itermanifest()] id = None @@ -519,11 +520,11 @@ class OPF(object): break if not media_type: media_type = 'application/xhtml+xml' - ans = etree.Element('{%s}item'%self.NAMESPACES['opf'], + ans = etree.Element('{%s}item'%self.NAMESPACES['opf'], attrib={'id':id, 'href':href, 'media-type':media_type}) ans.tail = '\n\t\t' return ans - + def replace_manifest_item(self, item, items): items = [self.create_manifest_item(*i) for i in items] for i, item2 in enumerate(items): @@ -532,7 +533,7 @@ class OPF(object): index = manifest.index(item) manifest[index:index+1] = items return [i.get('id') for i in items] - + def add_path_to_manifest(self, path, media_type): has_path = False path = os.path.abspath(path) @@ -546,22 +547,22 @@ class OPF(object): item = self.create_manifest_item(href, media_type) manifest = self.manifest_ppath(self.root)[0] manifest.append(item) - + def iterspine(self): return self.spine_path(self.root) - + def spine_items(self): for item in self.iterspine(): idref = item.get('idref', '') for x in self.itermanifest(): if x.get('id', None) == idref: yield x.get('href', '') - + def create_spine_item(self, idref): ans = etree.Element('{%s}itemref'%self.NAMESPACES['opf'], idref=idref) ans.tail = '\n\t\t' return ans - + def replace_spine_items_by_idref(self, idref, new_idrefs): items = list(map(self.create_spine_item, new_idrefs)) spine = self.XPath('/opf:package/*[re:match(name(), "spine", "i")]')(self.root)[0] @@ -569,31 +570,31 @@ class OPF(object): for x in old: i = spine.index(x) spine[i:i+1] = items - + def create_guide_element(self): e = etree.SubElement(self.root, '{%s}guide'%self.NAMESPACES['opf']) e.text = '\n ' e.tail = '\n' return e - + def remove_guide(self): self.guide = None for g in self.root.xpath('./*[re:match(name(), "guide", "i")]', namespaces={'re':'http://exslt.org/regular-expressions'}): self.root.remove(g) - + def create_guide_item(self, type, title, href): - e = etree.Element('{%s}reference'%self.NAMESPACES['opf'], + e = etree.Element('{%s}reference'%self.NAMESPACES['opf'], type=type, title=title, href=href) e.tail='\n' return e - + def add_guide_item(self, type, title, href): g = self.root.xpath('./*[re:match(name(), "guide", "i")]', namespaces={'re':'http://exslt.org/regular-expressions'})[0] g.append(self.create_guide_item(type, title, href)) - + def iterguide(self): return self.guide_path(self.root) - + def unquote_urls(self): def get_href(item): raw = unquote(item.get('href', '')) @@ -604,16 +605,16 @@ class OPF(object): item.set('href', get_href(item)) for item in self.iterguide(): item.set('href', get_href(item)) - + @apply def authors(): - + def fget(self): ans = [] for elem in self.authors_path(self.metadata): ans.extend([x.strip() for x in self.get_text(elem).split(',')]) return ans - + def fset(self, val): remove = list(self.authors_path(self.metadata)) for elem in remove: @@ -622,12 +623,12 @@ class OPF(object): attrib = {'{%s}role'%self.NAMESPACES['opf']: 'aut'} elem = self.create_metadata_element('creator', attrib=attrib) self.set_text(elem, author) - + return property(fget=fget, fset=fset) - + @apply def author_sort(): - + def fget(self): matches = self.authors_path(self.metadata) if matches: @@ -637,39 +638,65 @@ class OPF(object): ans = match.get('file-as', None) if ans: return ans - + def fset(self, val): matches = self.authors_path(self.metadata) if matches: + for key in matches[0].attrib: + if key.endswith('file-as'): + matches[0].attrib.pop(key) matches[0].set('file-as', unicode(val)) - + return property(fget=fget, fset=fset) - + + @apply + def title_sort(): + + def fget(self): + matches = self.title_path(self.metadata) + if matches: + for match in matches: + ans = match.get('{%s}file-as'%self.NAMESPACES['opf'], None) + if not ans: + ans = match.get('file-as', None) + if ans: + return ans + + def fset(self, val): + matches = self.title_path(self.metadata) + if matches: + for key in matches[0].attrib: + if key.endswith('file-as'): + matches[0].attrib.pop(key) + matches[0].set('file-as', unicode(val)) + + return property(fget=fget, fset=fset) + @apply def tags(): - + def fget(self): ans = [] for tag in self.tags_path(self.metadata): ans.append(self.get_text(tag)) return ans - + def fset(self, val): for tag in list(self.tags_path(self.metadata)): self.metadata.remove(tag) for tag in val: elem = self.create_metadata_element('subject') self.set_text(elem, unicode(tag)) - + return property(fget=fget, fset=fset) - + @apply def isbn(): - + def fget(self): for match in self.isbn_path(self.metadata): return self.get_text(match) or None - + def fset(self, val): matches = self.isbn_path(self.metadata) if not matches: @@ -682,11 +709,11 @@ class OPF(object): @apply def application_id(): - + def fget(self): for match in self.application_id_path(self.metadata): return self.get_text(match) or None - + def fset(self, val): matches = self.application_id_path(self.metadata) if not matches: @@ -696,14 +723,14 @@ class OPF(object): self.set_text(matches[0], unicode(val)) return property(fget=fget, fset=fset) - + @apply def book_producer(): - + def fget(self): for match in self.bkp_path(self.metadata): return self.get_text(match) or None - + def fset(self, val): matches = self.bkp_path(self.metadata) if not matches: @@ -712,8 +739,8 @@ class OPF(object): attrib=attrib)] self.set_text(matches[0], unicode(val)) return property(fget=fget, fset=fset) - - + + def guess_cover(self): ''' Try to guess a cover. Needed for some old/badly formed OPF files. @@ -733,11 +760,11 @@ class OPF(object): cpath = os.access(os.path.join(self.base_dir, prefix+suffix), os.R_OK) if os.access(os.path.join(self.base_dir, prefix+suffix), os.R_OK): return cpath - - + + @apply def cover(): - + def fget(self): if self.guide is not None: for t in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'): @@ -748,19 +775,19 @@ class OPF(object): return self.guess_cover() except: pass - + def fset(self, path): if self.guide is not None: self.guide.set_cover(path) for item in list(self.iterguide()): if 'cover' in item.get('type', ''): item.getparent().remove(item) - + else: g = self.create_guide_element() self.guide = Guide() self.guide.set_cover(path) - etree.SubElement(g, 'opf:reference', nsmap=self.NAMESPACES, + etree.SubElement(g, 'opf:reference', nsmap=self.NAMESPACES, attrib={'type':'cover', 'href':self.guide[-1].href()}) id = self.manifest.id_for_path(self.cover) if id is None: @@ -768,14 +795,14 @@ class OPF(object): for item in self.guide: if item.type.lower() == t: self.create_manifest_item(item.href(), mimetypes.guess_type(path)[0]) - - return property(fget=fget, fset=fset) - + + return property(fget=fget, fset=fset) + def get_metadata_element(self, name): matches = self.metadata_elem_path(self.metadata, name=name) if matches: return matches[-1] - + def create_metadata_element(self, name, attrib=None, is_dc=True): if is_dc: name = '{%s}%s' % (self.NAMESPACES['dc'], name) @@ -787,21 +814,24 @@ class OPF(object): nsmap=self.NAMESPACES) elem.tail = '\n' return elem - + def render(self, encoding='utf-8'): - return etree.tostring(self.root, encoding='utf-8', pretty_print=True) - + raw = etree.tostring(self.root, encoding=encoding, pretty_print=True) + if not raw.lstrip().startswith('\n'%encoding.upper()+raw + return raw + def smart_update(self, mi): - for attr in ('author_sort', 'title_sort', 'comments', 'category', + for attr in ('title', 'authors', 'author_sort', 'title_sort', 'publisher', 'series', 'series_index', 'rating', - 'isbn', 'language', 'tags', 'title', 'authors'): + 'isbn', 'language', 'tags', 'category', 'comments'): val = getattr(mi, attr, None) if val is not None and val != [] and val != (None, None): setattr(self, attr, val) - - + + class OPFCreator(MetaInformation): - + def __init__(self, base_path, *args, **kwargs): ''' Initialize. @@ -821,63 +851,64 @@ class OPFCreator(MetaInformation): self.guide = Guide() if self.cover: self.guide.set_cover(self.cover) - - + + def create_manifest(self, entries): ''' Create - + `entries`: List of (path, mime-type) If mime-type is None it is autodetected ''' - entries = map(lambda x: x if os.path.isabs(x[0]) else + entries = map(lambda x: x if os.path.isabs(x[0]) else (os.path.abspath(os.path.join(self.base_path, x[0])), x[1]), entries) self.manifest = Manifest.from_paths(entries) self.manifest.set_basedir(self.base_path) - + def create_manifest_from_files_in(self, files_and_dirs): entries = [] - + def dodir(dir): for spec in os.walk(dir): root, files = spec[0], spec[-1] for name in files: path = os.path.join(root, name) if os.path.isfile(path): - entries.append((path, None)) - + entries.append((path, None)) + for i in files_and_dirs: if os.path.isdir(i): dodir(i) else: entries.append((i, None)) - - self.create_manifest(entries) - + + self.create_manifest(entries) + def create_spine(self, entries): ''' Create the element. Must first call :method:`create_manifest`. - + `entries`: List of paths ''' - entries = map(lambda x: x if os.path.isabs(x) else + entries = map(lambda x: x if os.path.isabs(x) else os.path.abspath(os.path.join(self.base_path, x)), entries) self.spine = Spine.from_paths(entries, self.manifest) - + def set_toc(self, toc): ''' Set the toc. You must call :method:`create_spine` before calling this method. - + :param toc: A :class:`TOC` object ''' self.toc = toc - + def create_guide(self, guide_element): self.guide = Guide.from_opf_guide(guide_element, self.base_path) self.guide.set_basedir(self.base_path) - - def render(self, opf_stream, ncx_stream=None, ncx_manifest_entry=None): + + def render(self, opf_stream=sys.stdout, ncx_stream=None, + ncx_manifest_entry=None): from calibre.resources import opf_template from calibre.utils.genshi.template import MarkupTemplate template = MarkupTemplate(opf_template) @@ -910,14 +941,14 @@ class OPFCreator(MetaInformation): class OPFTest(unittest.TestCase): - + def setUp(self): self.stream = cStringIO.StringIO( '''\ - A Cool & © ß Title + A Cool & © ß Title Monkey Kitchen, Next OneTwo 123456789 @@ -932,34 +963,51 @@ class OPFTest(unittest.TestCase): ''' ) self.opf = OPF(self.stream, os.getcwd()) - - def testReading(self): - opf = self.opf + + def testReading(self, opf=None): + if opf is None: + opf = self.opf self.assertEqual(opf.title, u'A Cool & \xa9 \xdf Title') self.assertEqual(opf.authors, u'Monkey Kitchen,Next'.split(',')) self.assertEqual(opf.author_sort, 'Monkey') + self.assertEqual(opf.title_sort, 'Wow') self.assertEqual(opf.tags, ['One', 'Two']) self.assertEqual(opf.isbn, '123456789') self.assertEqual(opf.series, 'A one book series') - self.assertEqual(opf.series_index, None) + self.assertEqual(opf.series_index, 1) self.assertEqual(list(opf.itermanifest())[0].get('href'), 'a ~ b') - + def testWriting(self): for test in [('title', 'New & Title'), ('authors', ['One', 'Two']), ('author_sort', "Kitchen"), ('tags', ['Three']), - ('isbn', 'a'), ('rating', 3), ('series_index', 1)]: + ('isbn', 'a'), ('rating', 3), ('series_index', 1), + ('title_sort', 'ts')]: setattr(self.opf, *test) - self.assertEqual(getattr(self.opf, test[0]), test[1]) - + attr, val = test + self.assertEqual(getattr(self.opf, attr), val) + self.opf.render() + def testCreator(self): + opf = OPFCreator(os.getcwd(), self.opf) + buf = cStringIO.StringIO() + opf.render(buf) + raw = buf.getvalue() + self.testReading(opf=OPF(cStringIO.StringIO(raw), os.getcwd())) + + def testSmartUpdate(self): + self.opf.smart_update(MetaInformation(self.opf)) + self.testReading() + def suite(): return unittest.TestLoader().loadTestsFromTestCase(OPFTest) - + def test(): unittest.TextTestRunner(verbosity=2).run(suite()) + def option_parser(): + from calibre.ebooks.metadata import get_parser parser = get_parser('opf') parser.add_option('--language', default=None, help=_('Set the dc:language field')) return parser @@ -1006,7 +1054,7 @@ def main(args=sys.argv): print MetaInformation(OPF(open(opfpath, 'rb'), basedir)) return 0 - + if __name__ == '__main__': sys.exit(main()) diff --git a/src/calibre/ebooks/mobi/mobiml.py b/src/calibre/ebooks/mobi/mobiml.py index 50d7b298b9..7ecd127452 100644 --- a/src/calibre/ebooks/mobi/mobiml.py +++ b/src/calibre/ebooks/mobi/mobiml.py @@ -138,7 +138,8 @@ class MobiMLizer(object): return result def mobimlize_content(self, tag, text, bstate, istates): - bstate.content = True + if text or tag != 'br': + bstate.content = True istate = istates[-1] para = bstate.para if tag in SPECIAL_TAGS and not text: @@ -188,11 +189,6 @@ class MobiMLizer(object): vspace -= 1 if istate.halign != 'auto': para.attrib['align'] = istate.halign - if istate.ids: - last = bstate.body[-1] - for id in istate.ids: - last.addprevious(etree.Element(XHTML('a'), attrib={'id': id})) - istate.ids.clear() pstate = bstate.istate if tag in CONTENT_TAGS: bstate.inline = para @@ -200,6 +196,11 @@ class MobiMLizer(object): etree.SubElement(para, XHTML(tag), attrib=istate.attrib) elif tag in TABLE_TAGS: para.attrib['valign'] = 'top' + if istate.ids: + last = bstate.body[-1] + for id in istate.ids: + last.addprevious(etree.Element(XHTML('a'), attrib={'id': id})) + istate.ids.clear() if not text: return if not pstate or istate != pstate: diff --git a/src/calibre/ebooks/mobi/reader.py b/src/calibre/ebooks/mobi/reader.py index e2bb6f6d5f..6811f9ccda 100644 --- a/src/calibre/ebooks/mobi/reader.py +++ b/src/calibre/ebooks/mobi/reader.py @@ -121,6 +121,7 @@ class BookHeader(object): sublangid = (langcode >> 10) & 0xFF self.language = main_language.get(langid, 'ENGLISH') self.sublanguage = sub_language.get(sublangid, 'NEUTRAL') + self.mobi_version = struct.unpack('>I', raw[0x68:0x6c])[0] self.first_image_index = struct.unpack('>L', raw[0x6c:0x6c+4])[0] self.exth_flag, = struct.unpack('>L', raw[0x80:0x84]) @@ -132,11 +133,8 @@ class BookHeader(object): class MobiReader(object): - PAGE_BREAK_PAT = re.compile(r'(<[/]{0,1}mbp:pagebreak\s*[/]{0,1}>)+', re.IGNORECASE) - IMAGE_PATS = map(re.compile, (r'\shirecindex=[\'"]{0,1}(\d+)[\'"]{0,1}', - r'\srecindex=[\'"]{0,1}(\d+)[\'"]{0,1}', - r'\slorecindex=[\'"]{0,1}(\d+)[\'"]{0,1}')) + IMAGE_ATTRS = ('lowrecindex', 'recindex', 'hirecindex') def __init__(self, filename_or_stream, verbose=False): self.verbose = verbose @@ -247,6 +245,7 @@ class MobiReader(object): self.processed_html = re.sub(r'
', '', self.processed_html) if self.book_header.ancient and '')+'' + self.processed_html = self.processed_html.replace('\r\n', '\n') self.processed_html = self.processed_html.replace('> <', '>\n<') for t, c in [('b', 'bold'), ('i', 'italic')]: self.processed_html = re.sub(r'(?i)<%s>'%t, r''%c, self.processed_html) @@ -264,6 +263,7 @@ class MobiReader(object): 'x-large' : '5', 'xx-large' : '6', } + mobi_version = self.book_header.mobi_version for tag in root.iter(etree.Element): if tag.tag in ('country-region', 'place', 'placetype', 'placename', 'state', 'city'): @@ -290,6 +290,11 @@ class MobiReader(object): align = attrib.pop('align').strip() if align: styles.append('text-align: %s' % align) + if mobi_version == 1 and tag.tag == 'hr': + tag.tag = 'div' + styles.append('page-break-before: always') + styles.append('display: block') + styles.append('margin: 0') if styles: attrib['style'] = '; '.join(styles) @@ -300,6 +305,17 @@ class MobiReader(object): except ValueError: if sz in size_map.keys(): attrib['size'] = size_map[sz] + if 'filepos-id' in attrib: + attrib['id'] = attrib.pop('filepos-id') + if 'filepos' in attrib: + filepos = int(attrib.pop('filepos')) + attrib['href'] = "#filepos%d" % filepos + if tag.tag == 'img': + recindex = None + for attr in self.IMAGE_ATTRS: + recindex = attrib.pop(attr, None) or recindex + if recindex is not None: + attrib['src'] = 'images/%s.jpg' % recindex def create_opf(self, htmlfile, guide=None): mi = self.book_header.exth.mi @@ -399,38 +415,40 @@ class MobiReader(object): def replace_page_breaks(self): - self.processed_html = self.PAGE_BREAK_PAT.sub('
', - self.processed_html) + self.processed_html = self.PAGE_BREAK_PAT.sub( + '
', + self.processed_html) def add_anchors(self): if self.verbose: print 'Adding anchors...' positions = set([]) - link_pattern = re.compile(r'<[^<>]+filepos=[\'"]{0,1}(\d+)[^<>]*>', re.IGNORECASE) + link_pattern = re.compile(r'''<[^<>]+filepos=['"]{0,1}(\d+)[^<>]*>''', + re.IGNORECASE) for match in link_pattern.finditer(self.mobi_html): positions.add(int(match.group(1))) - positions = list(positions) - positions.sort() pos = 0 self.processed_html = '' - for end in positions: + end_tag_re = re.compile(r'<\s*/') + for end in sorted(positions): if end == 0: continue oend = end l = self.mobi_html.find('<', end) r = self.mobi_html.find('>', end) - if r > -1 and r < l: # Move out of tag - end = r+1 - self.processed_html += self.mobi_html[pos:end] + ''%(oend, oend) + anchor = '' + if r > -1 and (r < l or l == end or l == -1): + p = self.mobi_html.rfind('<', 0, end + 1) + if pos < end and p > -1 and \ + not end_tag_re.match(self.mobi_html[p:r]): + anchor = ' filepos-id="filepos%d"' + end = r + else: + end = r + 1 + self.processed_html += self.mobi_html[pos:end] + (anchor % oend) pos = end - self.processed_html += self.mobi_html[pos:] - fpat = re.compile(r'filepos=[\'"]{0,1}(\d+)[\'"]{0,1}', re.IGNORECASE) - def fpos_to_href(match): - return fpat.sub('href="#filepos%d"'%int(match.group(1)), match.group()) - self.processed_html = link_pattern.sub(fpos_to_href, - self.processed_html) - + def extract_images(self, processed_records, output_dir): if self.verbose: print 'Extracting images...' @@ -454,19 +472,6 @@ class MobiReader(object): path = os.path.join(output_dir, '%05d.jpg'%image_index) self.image_names.append(os.path.basename(path)) im.convert('RGB').save(open(path, 'wb'), format='JPEG') - - def fix_images(match): - tag = match.group() - for pat in self.IMAGE_PATS: - m = pat.search(tag) - if m: - return pat.sub(' src="images/%s.jpg"'%m.group(1), tag) - - - if hasattr(self, 'processed_html'): - self.processed_html = \ - re.compile(r'', re.IGNORECASE|re.DOTALL)\ - .sub(fix_images, self.processed_html) def get_metadata(stream): mr = MobiReader(stream) diff --git a/src/calibre/ebooks/oeb/base.py b/src/calibre/ebooks/oeb/base.py index b89be6b1ec..8e0fa3fbb2 100644 --- a/src/calibre/ebooks/oeb/base.py +++ b/src/calibre/ebooks/oeb/base.py @@ -6,84 +6,120 @@ from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Marshall T. Vandegrift ' -import os -import sys +import os, sys, re, uuid, copy +from mimetypes import types_map, guess_type from collections import defaultdict from types import StringTypes from itertools import izip, count, chain from urlparse import urldefrag, urlparse, urlunparse from urllib import unquote as urlunquote -import logging -import re -import uuid -import copy -from lxml import etree -from lxml import html +from lxml import etree, html +import calibre from calibre import LoggingInterface from calibre.translations.dynamic import translate from calibre.startup import get_lang +from calibre.ebooks.chardet import xml_to_unicode from calibre.ebooks.oeb.entitydefs import ENTITYDEFS from calibre.ebooks.metadata.epub import CoverRenderer from calibre.ptempfile import TemporaryDirectory -XML_NS = 'http://www.w3.org/XML/1998/namespace' -XHTML_NS = 'http://www.w3.org/1999/xhtml' -OEB_DOC_NS = 'http://openebook.org/namespaces/oeb-document/1.0/' -OPF1_NS = 'http://openebook.org/namespaces/oeb-package/1.0/' -OPF2_NS = 'http://www.idpf.org/2007/opf' -OPF_NSES = set([OPF1_NS, OPF2_NS]) -DC09_NS = 'http://purl.org/metadata/dublin_core' -DC10_NS = 'http://purl.org/dc/elements/1.0/' -DC11_NS = 'http://purl.org/dc/elements/1.1/' -DC_NSES = set([DC09_NS, DC10_NS, DC11_NS]) -XSI_NS = 'http://www.w3.org/2001/XMLSchema-instance' -DCTERMS_NS = 'http://purl.org/dc/terms/' -NCX_NS = 'http://www.daisy.org/z3986/2005/ncx/' -SVG_NS = 'http://www.w3.org/2000/svg' -XLINK_NS = 'http://www.w3.org/1999/xlink' -CALIBRE_NS = 'http://calibre.kovidgoyal.net/2009/metadata' -XPNSMAP = {'h': XHTML_NS, 'o1': OPF1_NS, 'o2': OPF2_NS, - 'd09': DC09_NS, 'd10': DC10_NS, 'd11': DC11_NS, - 'xsi': XSI_NS, 'dt': DCTERMS_NS, 'ncx': NCX_NS, - 'svg': SVG_NS, 'xl': XLINK_NS} +XML_NS = 'http://www.w3.org/XML/1998/namespace' +XHTML_NS = 'http://www.w3.org/1999/xhtml' +OEB_DOC_NS = 'http://openebook.org/namespaces/oeb-document/1.0/' +OPF1_NS = 'http://openebook.org/namespaces/oeb-package/1.0/' +OPF2_NS = 'http://www.idpf.org/2007/opf' +OPF_NSES = set([OPF1_NS, OPF2_NS]) +DC09_NS = 'http://purl.org/metadata/dublin_core' +DC10_NS = 'http://purl.org/dc/elements/1.0/' +DC11_NS = 'http://purl.org/dc/elements/1.1/' +DC_NSES = set([DC09_NS, DC10_NS, DC11_NS]) +XSI_NS = 'http://www.w3.org/2001/XMLSchema-instance' +DCTERMS_NS = 'http://purl.org/dc/terms/' +NCX_NS = 'http://www.daisy.org/z3986/2005/ncx/' +SVG_NS = 'http://www.w3.org/2000/svg' +XLINK_NS = 'http://www.w3.org/1999/xlink' +CALIBRE_NS = 'http://calibre.kovidgoyal.net/2009/metadata' +XPNSMAP = { + 'h' : XHTML_NS, 'o1' : OPF1_NS, 'o2' : OPF2_NS, + 'd09': DC09_NS, 'd10': DC10_NS, 'd11': DC11_NS, + 'xsi': XSI_NS, 'dt' : DCTERMS_NS, 'ncx': NCX_NS, + 'svg': SVG_NS, 'xl' : XLINK_NS + } DC_PREFIXES = ('d11', 'd10', 'd09') -def XML(name): return '{%s}%s' % (XML_NS, name) -def XHTML(name): return '{%s}%s' % (XHTML_NS, name) -def OPF(name): return '{%s}%s' % (OPF2_NS, name) -def DC(name): return '{%s}%s' % (DC11_NS, name) -def XSI(name): return '{%s}%s' % (XSI_NS, name) -def DCTERMS(name): return '{%s}%s' % (DCTERMS_NS, name) -def NCX(name): return '{%s}%s' % (NCX_NS, name) -def SVG(name): return '{%s}%s' % (SVG_NS, name) -def XLINK(name): return '{%s}%s' % (XLINK_NS, name) -def CALIBRE(name): return '{%s}%s' % (CALIBRE_NS, name) -EPUB_MIME = 'application/epub+zip' -XHTML_MIME = 'application/xhtml+xml' -CSS_MIME = 'text/css' -NCX_MIME = 'application/x-dtbncx+xml' -OPF_MIME = 'application/oebps-package+xml' -OEB_DOC_MIME = 'text/x-oeb1-document' -OEB_CSS_MIME = 'text/x-oeb1-css' -OPENTYPE_MIME = 'font/opentype' -GIF_MIME = 'image/gif' -JPEG_MIME = 'image/jpeg' -PNG_MIME = 'image/png' -SVG_MIME = 'image/svg+xml' -BINARY_MIME = 'application/octet-stream' +def XML(name): + return '{%s}%s' % (XML_NS, name) -OEB_STYLES = set([CSS_MIME, OEB_CSS_MIME, 'text/x-oeb-css']) -OEB_DOCS = set([XHTML_MIME, 'text/html', OEB_DOC_MIME, 'text/x-oeb-document']) +def XHTML(name): + return '{%s}%s' % (XHTML_NS, name) + +def OPF(name): + return '{%s}%s' % (OPF2_NS, name) + +def DC(name): + return '{%s}%s' % (DC11_NS, name) + +def XSI(name): + return '{%s}%s' % (XSI_NS, name) + +def DCTERMS(name): + return '{%s}%s' % (DCTERMS_NS, name) + +def NCX(name): + return '{%s}%s' % (NCX_NS, name) + +def SVG(name): + return '{%s}%s' % (SVG_NS, name) + +def XLINK(name): + return '{%s}%s' % (XLINK_NS, name) + +def CALIBRE(name): + return '{%s}%s' % (CALIBRE_NS, name) + +def LINK_SELECTORS(): + results = [] + for expr in ('h:head/h:link/@href', 'h:body//h:a/@href', + 'h:body//h:img/@src', 'h:body//h:object/@data', + 'h:body//*/@xl:href', '//ncx:content/@src', + 'o2:page/@href'): + results.append(etree.XPath(expr, namespaces=XPNSMAP)) + return results + +LINK_SELECTORS = LINK_SELECTORS() + +EPUB_MIME = types_map['.epub'] +XHTML_MIME = types_map['.xhtml'] +CSS_MIME = types_map['.css'] +NCX_MIME = types_map['.ncx'] +OPF_MIME = types_map['.opf'] +PAGE_MAP_MIME = 'application/oebps-page-map+xml' +OEB_DOC_MIME = 'text/x-oeb1-document' +OEB_CSS_MIME = 'text/x-oeb1-css' +OPENTYPE_MIME = 'application/x-font-opentype' +GIF_MIME = types_map['.gif'] +JPEG_MIME = types_map['.jpeg'] +PNG_MIME = types_map['.png'] +SVG_MIME = types_map['.svg'] +BINARY_MIME = 'application/octet-stream' + +OEB_STYLES = set([CSS_MIME, OEB_CSS_MIME, 'text/x-oeb-css']) +OEB_DOCS = set([XHTML_MIME, 'text/html', OEB_DOC_MIME, 'text/x-oeb-document']) OEB_RASTER_IMAGES = set([GIF_MIME, JPEG_MIME, PNG_MIME]) -OEB_IMAGES = set([GIF_MIME, JPEG_MIME, PNG_MIME, SVG_MIME]) +OEB_IMAGES = set([GIF_MIME, JPEG_MIME, PNG_MIME, SVG_MIME]) MS_COVER_TYPE = 'other.ms-coverimage-standard' -ENTITY_RE = re.compile(r'&([a-zA-Z_:][a-zA-Z0-9.-_:]+);') -COLLAPSE_RE = re.compile(r'[ \t\r\n\v]+') -QNAME_RE = re.compile(r'^[{][^{}]+[}][^{}]+$') +ENTITY_RE = re.compile(r'&([a-zA-Z_:][a-zA-Z0-9.-_:]+);') +COLLAPSE_RE = re.compile(r'[ \t\r\n\v]+') +QNAME_RE = re.compile(r'^[{][^{}]+[}][^{}]+$') PREFIXNAME_RE = re.compile(r'^[^:]+[:][^:]+') +XMLDECL_RE = re.compile(r'^\s*<[?]xml.*?[?]>') +CSSURL_RE = re.compile(r'''url[(](?P["']?)(?P[^)]+)(?P=q)[)]''') + +RECOVER_PARSER = etree.XMLParser(recover=True) + def element(parent, *args, **kwargs): if parent is not None: @@ -134,21 +170,28 @@ def xpath(elem, expr): def xml2str(root): return etree.tostring(root, encoding='utf-8', xml_declaration=True) -ASCII_CHARS = set(chr(x) for x in xrange(128)) -URL_SAFE = set(u'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - u'abcdefghijklmnopqrstuvwxyz' - u'0123456789' u'_.-/~') -URL_UNSAFE = ASCII_CHARS - URL_SAFE +ASCII_CHARS = set(chr(x) for x in xrange(128)) +UNIBYTE_CHARS = set(chr(x) for x in xrange(256)) +URL_SAFE = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789' '_.-/~') +URL_UNSAFE = [ASCII_CHARS - URL_SAFE, UNIBYTE_CHARS - URL_SAFE] + def urlquote(href): result = [] + unsafe = 0 if isinstance(href, unicode) else 1 + unsafe = URL_UNSAFE[unsafe] for char in href: - if char in URL_UNSAFE: + if char in unsafe: char = "%%%02x" % ord(char) result.append(char) return ''.join(result) def urlnormalize(href): parts = urlparse(href) + if not parts.scheme: + path, frag = urldefrag(href) + parts = ('', '', path, '', '', frag) parts = (part.replace('\\', '/') for part in parts) parts = (urlunquote(part) for part in parts) parts = (urlquote(part) for part in parts) @@ -177,7 +220,7 @@ class AbstractContainer(object): class DirContainer(AbstractContainer): def __init__(self, rootdir): - self.rootdir = rootdir + self.rootdir = unicode(rootdir) def read(self, path): path = os.path.join(self.rootdir, path) @@ -197,36 +240,53 @@ class DirContainer(AbstractContainer): return os.path.isfile(urlunquote(path)) class DirWriter(object): - def __init__(self, version=2.0): + def __init__(self, version='2.0', page_map=False): self.version = version + self.page_map = page_map def dump(self, oeb, path): + version = int(self.version[0]) + opfname = None + if os.path.splitext(path)[1].lower() == '.opf': + opfname = os.path.basename(path) + path = os.path.dirname(path) if not os.path.isdir(path): os.mkdir(path) output = DirContainer(path) for item in oeb.manifest.values(): output.write(item.href, str(item)) - metadata = oeb.to_opf2() if self.version == 2 else oeb.to_opf1() - for href, data in metadata.values(): + if version == 1: + metadata = oeb.to_opf1() + elif version == 2: + metadata = oeb.to_opf2(page_map=self.page_map) + else: + raise OEBError("Unrecognized OPF version %r" % self.version) + for mime, (href, data) in metadata.items(): + if opfname and mime == OPF_MIME: + href = opfname output.write(href, xml2str(data)) return class Metadata(object): - DC_TERMS = set(['contributor', 'coverage', 'creator', 'date', + DC_TERMS = set([ + 'contributor', 'coverage', 'creator', 'date', 'description', 'format', 'identifier', 'language', 'publisher', 'relation', 'rights', 'source', 'subject', - 'title', 'type']) + 'title', 'type' + ]) CALIBRE_TERMS = set(['series', 'series_index', 'rating']) - OPF_ATTRS = {'role': OPF('role'), 'file-as': OPF('file-as'), - 'scheme': OPF('scheme'), 'event': OPF('event'), - 'type': XSI('type'), 'lang': XML('lang'), 'id': 'id'} - OPF1_NSMAP = {'dc': DC11_NS, 'oebpackage': OPF1_NS} - OPF2_NSMAP = {'opf': OPF2_NS, 'dc': DC11_NS, 'dcterms': DCTERMS_NS, - 'xsi': XSI_NS, 'calibre': CALIBRE_NS} + OPF_ATTRS = {'role': OPF('role'), 'file-as': OPF('file-as'), + 'scheme': OPF('scheme'), 'event': OPF('event'), + 'type': XSI('type'), 'lang': XML('lang'), 'id': 'id'} + OPF1_NSMAP = {'dc': DC11_NS, 'oebpackage': OPF1_NS} + OPF2_NSMAP = {'opf': OPF2_NS, 'dc': DC11_NS, 'dcterms': DCTERMS_NS, + 'xsi': XSI_NS, 'calibre': CALIBRE_NS} class Item(object): + class Attribute(object): + def __init__(self, attr, allowed=None): if not callable(attr): attr_, attr = attr, lambda term: attr_ @@ -277,17 +337,14 @@ class Metadata(object): if attr != nsattr: attrib[nsattr] = attrib.pop(attr) - def scheme(term): - if term == OPF('meta'): - return 'scheme' - return OPF('scheme') - scheme = Attribute(scheme, [DC('identifier'), OPF('meta')]) + scheme = Attribute(lambda term : 'scheme' if term == OPF('meta') else OPF('scheme'), + [DC('identifier'), OPF('meta')]) file_as = Attribute(OPF('file-as'), [DC('creator'), DC('contributor')]) - role = Attribute(OPF('role'), [DC('creator'), DC('contributor')]) - event = Attribute(OPF('event'), [DC('date')]) - id = Attribute('id') - type = Attribute(XSI('type'), [DC('date'), DC('format'), DC('type')]) - lang = Attribute(XML('lang'), [DC('contributor'), DC('coverage'), + role = Attribute(OPF('role'), [DC('creator'), DC('contributor')]) + event = Attribute(OPF('event'), [DC('date')]) + id = Attribute('id') + type = Attribute(XSI('type'), [DC('date'), DC('format'), DC('type')]) + lang = Attribute(XML('lang'), [DC('contributor'), DC('coverage'), DC('creator'), DC('publisher'), DC('relation'), DC('rights'), DC('source'), DC('subject'), @@ -368,6 +425,7 @@ class Metadata(object): def __getattr__(self, term): return self.items[term] + @apply def _nsmap(): def fget(self): nsmap = {} @@ -376,8 +434,8 @@ class Metadata(object): nsmap.update(item.nsmap) return nsmap return property(fget=fget) - _nsmap = _nsmap() + @apply def _opf1_nsmap(): def fget(self): nsmap = self._nsmap @@ -386,15 +444,16 @@ class Metadata(object): del nsmap[key] return nsmap return property(fget=fget) - _opf1_nsmap = _opf1_nsmap() + + @apply def _opf2_nsmap(): def fget(self): nsmap = self._nsmap nsmap.update(self.OPF2_NSMAP) return nsmap return property(fget=fget) - _opf2_nsmap = _opf2_nsmap() + def to_opf1(self, parent=None): nsmap = self._opf1_nsmap @@ -421,7 +480,9 @@ class Metadata(object): class Manifest(object): + class Item(object): + NUM_RE = re.compile('^(.*)([0-9][0-9.]*)(?=[.]|$)') META_XP = XPath('/h:html/h:head/h:meta[@http-equiv="Content-Type"]') @@ -444,9 +505,9 @@ class Manifest(object): % (self.id, self.href, self.media_type) def _force_xhtml(self, data): - # Possibly decode in user-specified encoding - if self.oeb.encoding is not None: - data = data.decode(self.oeb.encoding, 'replace') + # Convert to Unicode and normalize line endings + data = self.oeb.decode(data) + data = XMLDECL_RE.sub('', data) # Handle broken XHTML w/ SVG (ugh) if 'svg:' in data and SVG_NS not in data: data = data.replace( @@ -471,7 +532,10 @@ class Manifest(object): if elem.text: elem.text = elem.text.strip('-') data = etree.tostring(data, encoding=unicode) - data = etree.fromstring(data) + try: + data = etree.fromstring(data) + except etree.XMLSyntaxError: + data = etree.fromstring(data, parser=RECOVER_PARSER) # Force into the XHTML namespace if barename(data.tag) != 'html': raise OEBError( @@ -493,9 +557,6 @@ class Manifest(object): for elem in data: nroot.append(elem) data = nroot - # Remove any encoding-specifying elements - for meta in self.META_XP(data): - meta.getparent().remove(meta) # Ensure has a head = xpath(data, '/h:html/h:head') head = head[0] if head else None @@ -511,6 +572,12 @@ class Manifest(object): 'File %r missing element' % self.href) title = etree.SubElement(head, XHTML('title')) title.text = self.oeb.translate(__('Unknown')) + # Remove any encoding-specifying <meta/> elements + for meta in self.META_XP(data): + meta.getparent().remove(meta) + etree.SubElement(head, XHTML('meta'), + attrib={'http-equiv': 'Content-Type', + 'content': '%s; charset=utf-8' % XHTML_NS}) # Ensure has a <body/> if not xpath(data, '/h:html/h:body'): self.oeb.logger.warn( @@ -518,6 +585,7 @@ class Manifest(object): etree.SubElement(data, XHTML('body')) return data + @apply def data(): def fget(self): if self._data is not None: @@ -527,6 +595,8 @@ class Manifest(object): data = self._force_xhtml(data) elif self.media_type[-4:] in ('+xml', '/xml'): data = etree.fromstring(data) + elif self.media_type in OEB_STYLES: + data = self.oeb.decode(data) self._data = data return data def fset(self, value): @@ -534,12 +604,13 @@ class Manifest(object): def fdel(self): self._data = None return property(fget, fset, fdel) - data = data() - + def __str__(self): data = self.data if isinstance(data, etree._Element): return xml2str(data) + if isinstance(data, unicode): + return data.encode('utf-8') return str(data) def __eq__(self, other): @@ -563,7 +634,9 @@ class Manifest(object): return cmp(skey, okey) def relhref(self, href): - if '/' not in self.href or ':' in href: + if urlparse(href).scheme: + return href + if '/' not in self.href: return href base = os.path.dirname(self.href).split('/') target, frag = urldefrag(href) @@ -579,7 +652,12 @@ class Manifest(object): return relhref def abshref(self, href): - if '/' not in self.href or ':' in href: + if urlparse(href).scheme: + return href + path, frag = urldefrag(href) + if not path: + return '#'.join((self.href, frag)) + if '/' not in self.href: return href dirname = os.path.dirname(self.href) href = os.path.join(dirname, href) @@ -606,18 +684,20 @@ class Manifest(object): if item in self.oeb.spine: self.oeb.spine.remove(item) - def generate(self, id, href): - href = urlnormalize(href) - base = id - index = 1 - while id in self.ids: - id = base + str(index) - index += 1 - base, ext = os.path.splitext(href) - index = 1 - while href in self.hrefs: - href = base + str(index) + ext - index += 1 + def generate(self, id=None, href=None): + if id is not None: + base = id + index = 1 + while id in self.ids: + id = base + str(index) + index += 1 + if href is not None: + href = urlnormalize(href) + base, ext = os.path.splitext(href) + index = 1 + while href in self.hrefs: + href = base + str(index) + ext + index += 1 return id, href def __iter__(self): @@ -670,6 +750,7 @@ class Manifest(object): class Spine(object): + def __init__(self, oeb): self.oeb = oeb self.items = [] @@ -735,7 +816,9 @@ class Spine(object): class Guide(object): + class Reference(object): + _TYPES_TITLES = [('cover', __('Cover')), ('title-page', __('Title Page')), ('toc', __('Table of Contents')), @@ -774,24 +857,24 @@ class Guide(object): return 'Reference(type=%r, title=%r, href=%r)' \ % (self.type, self.title, self.href) + @apply def _order(): def fget(self): return self.ORDER.get(self.type, self.type) return property(fget=fget) - _order = _order() def __cmp__(self, other): if not isinstance(other, Guide.Reference): return NotImplemented return cmp(self._order, other._order) + @apply def item(): def fget(self): - path, frag = urldefrag(self.href) + path = urldefrag(self.href)[0] hrefs = self.oeb.manifest.hrefs return hrefs.get(path, None) return property(fget=fget) - item = item() def __init__(self, oeb): self.oeb = oeb @@ -846,6 +929,7 @@ class Guide(object): class TOC(object): + # This needs beefing up to support the interface of toc.TOC def __init__(self, title=None, href=None, klass=None, id=None): self.title = title self.href = urlnormalize(href) if href else href @@ -892,27 +976,75 @@ class TOC(object): node.to_opf1(tour) return tour - def to_ncx(self, parent, order=None, depth=1): - if not order: order = [0] + def to_ncx(self, parent, depth=1): for node in self.nodes: - order[0] += 1 - playOrder = str(order[0]) - id = self.id or 'np' + playOrder - point = etree.SubElement(parent, - NCX('navPoint'), id=id, playOrder=playOrder) - if self.klass: - point.attrib['class'] = node.klass + id = node.id or unicode(uuid.uuid4()) + attrib = {'id': id, 'playOrder': '0'} + if node.klass: + attrib['class'] = node.klass + point = element(parent, NCX('navPoint'), attrib=attrib) label = etree.SubElement(point, NCX('navLabel')) - etree.SubElement(label, NCX('text')).text = node.title + element(label, NCX('text')).text = node.title href = node.href if depth > 1 else urldefrag(node.href)[0] - child = etree.SubElement(point, - NCX('content'), attrib={'src': href}) - node.to_ncx(point, order, depth+1) + element(point, NCX('content'), src=href) + node.to_ncx(point, depth+1) return parent + +class PageList(object): + class Page(object): + def __init__(self, name, href, type='normal', klass=None, id=None): + self.name = name + self.href = urlnormalize(href) + self.type = type + self.id = id + self.klass = klass + + def __init__(self): + self.pages = [] + + def add(self, name, href, type='normal', klass=None, id=None): + page = self.Page(name, href, type, klass, id) + self.pages.append(page) + return page + + def __len__(self): + return len(self.pages) + + def __iter__(self): + for page in self.pages: + yield page + + def __getitem__(self, index): + return self.pages[index] + + def to_ncx(self, parent=None): + plist = element(parent, NCX('pageList'), id=str(uuid.uuid4())) + values = dict((t, count(1)) for t in ('front', 'normal', 'special')) + for page in self.pages: + id = page.id or unicode(uuid.uuid4()) + type = page.type + value = str(values[type].next()) + attrib = {'id': id, 'value': value, 'type': type, 'playOrder': '0'} + if page.klass: + attrib['class'] = page.klass + ptarget = element(plist, NCX('pageTarget'), attrib=attrib) + label = element(ptarget, NCX('navLabel')) + element(label, NCX('text')).text = page.name + element(ptarget, NCX('content'), src=page.href) + return plist + + def to_page_map(self): + pmap = etree.Element(OPF('page-map'), nsmap={None: OPF2_NS}) + for page in self.pages: + element(pmap, OPF('page'), name=page.name, href=page.href) + return pmap + + class OEBBook(object): - COVER_SVG_XP = XPath('h:body//svg:svg[position() = 1]') + + COVER_SVG_XP = XPath('h:body//svg:svg[position() = 1]') COVER_OBJECT_XP = XPath('h:body//h:object[@data][position() = 1]') def __init__(self, opfpath=None, container=None, encoding=None, @@ -941,13 +1073,11 @@ class OEBBook(object): metadata = etree.SubElement(nroot, OPF('metadata'), nsmap=nsmap) ignored = (OPF('dc-metadata'), OPF('x-metadata')) for elem in xpath(opf, 'o2:metadata//*'): + if elem.tag in ignored: + continue if namespace(elem.tag) in DC_NSES: tag = barename(elem.tag).lower() elem.tag = '{%s}%s' % (DC11_NS, tag) - for name in elem.attrib: - if name in ('role', 'file-as', 'scheme', 'event'): - nsname = '{%s}%s' % (OPF2_NS, name) - elem.attrib[nsname] = elem.attrib.pop(name) metadata.append(elem) for element in xpath(opf, 'o2:metadata//o2:meta'): metadata.append(element) @@ -957,13 +1087,15 @@ class OEBBook(object): return nroot def _read_opf(self, opfpath): - opf = self.container.read(opfpath) + data = self.container.read(opfpath) + data = self.decode(data) + data = XMLDECL_RE.sub('', data) try: - opf = etree.fromstring(opf) + opf = etree.fromstring(data) except etree.XMLSyntaxError: repl = lambda m: ENTITYDEFS.get(m.group(1), m.group(0)) - opf = ENTITY_RE.sub(repl, opf) - opf = etree.fromstring(opf) + data = ENTITY_RE.sub(repl, data) + opf = etree.fromstring(data) self.logger.warn('OPF contains invalid HTML named entities') ns = namespace(opf.tag) if ns not in ('', OPF1_NS, OPF2_NS): @@ -972,7 +1104,7 @@ class OEBBook(object): return opf def _metadata_from_opf(self, opf): - uid = opf.get('unique-identifier', 'calibre-uuid') + uid = opf.get('unique-identifier', None) self.uid = None self.metadata = metadata = Metadata(self) for elem in xpath(opf, '/o2:package/o2:metadata//*'): @@ -993,11 +1125,15 @@ class OEBBook(object): haveuuid = True if 'id' in ident.attrib: haveid = True - if not haveuuid and haveid: + if not (haveuuid and haveid): bookid = "urn:uuid:%s" % str(uuid.uuid4()) metadata.add('identifier', bookid, id='calibre-uuid') + if uid is None: + self.logger.warn(u'Unique-identifier not specified') for item in metadata.identifier: - if item.id == uid: + if not item.id: + continue + if uid is None or item.id == uid: self.uid = item break else: @@ -1015,6 +1151,45 @@ class OEBBook(object): if not metadata.title: self.logger.warn('Title not specified') metadata.add('title', self.translate(__('Unknown'))) + + def _manifest_add_missing(self): + manifest = self.manifest + known = set(manifest.hrefs) + unchecked = set(manifest.values()) + while unchecked: + new = set() + for item in unchecked: + if (item.media_type in OEB_DOCS or + item.media_type[-4:] in ('/xml', '+xml')) and \ + item.data is not None: + hrefs = [sel(item.data) for sel in LINK_SELECTORS] + for href in chain(*hrefs): + href, _ = urldefrag(href) + if not href: + continue + href = item.abshref(urlnormalize(href)) + scheme = urlparse(href).scheme + if not scheme and href not in known: + new.add(href) + elif item.media_type in OEB_STYLES: + for match in CSSURL_RE.finditer(item.data): + href, _ = urldefrag(match.group('url')) + href = item.abshref(urlnormalize(href)) + scheme = urlparse(href).scheme + if not scheme and href not in known: + new.add(href) + unchecked.clear() + for href in new: + known.add(href) + if not self.container.exists(href): + self.logger.warn('Referenced file %r not found' % href) + continue + self.logger.warn('Referenced file %r not in manifest' % href) + id, _ = manifest.generate(id='added') + guessed = guess_type(href)[0] + media_type = guessed or BINARY_MIME + added = manifest.add(id, href, media_type) + unchecked.add(added) def _manifest_from_opf(self, opf): self.manifest = manifest = Manifest(self) @@ -1023,7 +1198,10 @@ class OEBBook(object): href = elem.get('href') media_type = elem.get('media-type', None) if media_type is None: - media_type = elem.get('mediatype', BINARY_MIME) + media_type = elem.get('mediatype', None) + if media_type is None or media_type == 'text/xml': + guessed = guess_type(href)[0] + media_type = guessed or media_type or BINARY_MIME fallback = elem.get('fallback') if href in manifest.hrefs: self.logger.warn(u'Duplicate manifest entry for %r' % href) @@ -1035,6 +1213,40 @@ class OEBBook(object): self.logger.warn(u'Duplicate manifest id %r' % id) id, href = manifest.generate(id, href) manifest.add(id, href, media_type, fallback) + self._manifest_add_missing() + + def _spine_add_extra(self): + manifest = self.manifest + spine = self.spine + unchecked = set(spine) + selector = XPath('h:body//h:a/@href') + extras = set() + while unchecked: + new = set() + for item in unchecked: + if item.media_type not in OEB_DOCS: + # TODO: handle fallback chains + continue + for href in selector(item.data): + href, _ = urldefrag(href) + if not href: + continue + href = item.abshref(urlnormalize(href)) + if href not in manifest.hrefs: + continue + found = manifest.hrefs[href] + if found.media_type not in OEB_DOCS or \ + found in spine or found in extras: + continue + new.add(found) + extras.update(new) + unchecked = new + version = int(self.version[0]) + for item in sorted(extras): + if version >= 2: + self.logger.warn( + 'Spine-referenced file %r not in spine' % item.href) + spine.add(item, linear=False) def _spine_from_opf(self, opf): self.spine = spine = Spine(self) @@ -1045,69 +1257,86 @@ class OEBBook(object): continue item = self.manifest[idref] spine.add(item, elem.get('linear')) - extras = [] - for item in self.manifest.values(): - if item.media_type in OEB_DOCS \ - and item not in spine: - extras.append(item) - extras.sort() - for item in extras: - spine.add(item, False) if len(spine) == 0: raise OEBError("Spine is empty") - + self._spine_add_extra() + def _guide_from_opf(self, opf): self.guide = guide = Guide(self) for elem in xpath(opf, '/o2:package/o2:guide/o2:reference'): href = elem.get('href') - path, frag = urldefrag(href) + path = urldefrag(href)[0] if path not in self.manifest.hrefs: self.logger.warn(u'Guide reference %r not found' % href) continue guide.add(elem.get('type'), elem.get('title'), href) - - def _toc_from_navpoint(self, toc, navpoint): + + def _find_ncx(self, opf): + result = xpath(opf, '/o2:package/o2:spine/@toc') + if result: + id = result[0] + if id not in self.manifest.ids: + return None + item = self.manifest.ids[id] + self.manifest.remove(item) + return item + for item in self.manifest.values(): + if item.media_type == NCX_MIME: + self.manifest.remove(item) + return item + return None + + def _toc_from_navpoint(self, item, toc, navpoint): children = xpath(navpoint, 'ncx:navPoint') for child in children: title = ''.join(xpath(child, 'ncx:navLabel/ncx:text/text()')) - href = xpath(child, 'ncx:content/@src')[0] + title = COLLAPSE_RE.sub(' ', title.strip()) + href = xpath(child, 'ncx:content/@src') + if not title or not href: + continue + href = item.abshref(urlnormalize(href[0])) + path, _ = urldefrag(href) + if path not in self.manifest.hrefs: + self.logger.warn('TOC reference %r not found' % href) + continue id = child.get('id') klass = child.get('class') node = toc.add(title, href, id=id, klass=klass) - self._toc_from_navpoint(node, child) - - def _toc_from_ncx(self, opf): - result = xpath(opf, '/o2:package/o2:spine/@toc') - if not result: - expr = '/o2:package/o2:manifest/o2:item[@media-type="%s"]/@id' - result = xpath(opf, expr % NCX_MIME) - if len(result) != 1: - return False - id = result[0] - if id not in self.manifest.ids: + self._toc_from_navpoint(item, node, child) + + def _toc_from_ncx(self, item): + if item is None: return False - item = self.manifest.ids[id] ncx = item.data - self.manifest.remove(item) - title = xpath(ncx, 'ncx:docTitle/ncx:text/text()') - title = title[0].strip() if title else unicode(self.metadata.title[0]) + title = ''.join(xpath(ncx, 'ncx:docTitle/ncx:text/text()')) + title = COLLAPSE_RE.sub(' ', title.strip()) + title = title or unicode(self.metadata.title[0]) self.toc = toc = TOC(title) navmaps = xpath(ncx, 'ncx:navMap') for navmap in navmaps: - self._toc_from_navpoint(toc, navmap) + self._toc_from_navpoint(item, toc, navmap) return True - + def _toc_from_tour(self, opf): - result = xpath(opf, '/o2:package/o2:tours/o2:tour') + result = xpath(opf, 'o2:tours/o2:tour') if not result: return False tour = result[0] self.toc = toc = TOC(tour.get('title')) sites = xpath(tour, 'o2:site') for site in sites: - toc.add(site.get('title'), site.get('href')) + title = site.get('title') + href = site.get('href') + if not title or not href: + continue + path, _ = urldefrag(urlnormalize(href)) + if path not in self.manifest.hrefs: + self.logger.warn('TOC reference %r not found' % href) + continue + id = site.get('id') + toc.add(title, href, id=id) return True - + def _toc_from_html(self, opf): if 'toc' not in self.guide: return False @@ -1127,11 +1356,12 @@ class OEBBook(object): order = [] for anchor in xpath(html, './/h:a[@href]'): href = anchor.attrib['href'] + href = item.abshref(urlnormalize(href)) path, frag = urldefrag(href) - if not path: - href = '#'.join((itempath, frag)) + if path not in self.manifest.hrefs: + continue title = ' '.join(xpath(anchor, './/text()')) - href = urlnormalize(href) + title = COLLAPSE_RE.sub(' ', title.strip()) if href not in titles: order.append(href) titles[href].append(title) @@ -1146,15 +1376,17 @@ class OEBBook(object): for item in self.spine: if not item.linear: continue html = item.data - title = xpath(html, '/h:html/h:head/h:title/text()') - title = title[0].strip() if title else None - if title: titles.append(title) + title = ''.join(xpath(html, '/h:html/h:head/h:title/text()')) + title = COLLAPSE_RE.sub(' ', title.strip()) + if title: + titles.append(title) headers.append('(unlabled)') for tag in ('h1', 'h2', 'h3', 'h4', 'h5', 'strong'): - expr = '/h:html/h:body//h:%s[position()=1]/text()' % (tag,) - header = xpath(html, expr) + expr = '/h:html/h:body//h:%s[position()=1]/text()' + header = ''.join(xpath(html, expr % tag)) + header = COLLAPSE_RE.sub(' ', header.strip()) if header: - headers[-1] = header[0] + headers[-1] = header break use = titles if len(titles) > len(set(titles)): @@ -1164,17 +1396,81 @@ class OEBBook(object): toc.add(title, item.href) return True - def _toc_from_opf(self, opf): - if self._toc_from_ncx(opf): return + def _toc_from_opf(self, opf, item): + if self._toc_from_ncx(item): return if self._toc_from_tour(opf): return + self.logger.warn('No metadata table of contents found') if self._toc_from_html(opf): return self._toc_from_spine(opf) - + + def _pages_from_ncx(self, opf, item): + if item is None: + return False + ncx = item.data + ptargets = xpath(ncx, 'ncx:pageList/ncx:pageTarget') + if not ptargets: + return False + pages = self.pages = PageList() + for ptarget in ptargets: + name = ''.join(xpath(ptarget, 'ncx:navLabel/ncx:text/text()')) + name = COLLAPSE_RE.sub(' ', name.strip()) + href = xpath(ptarget, 'ncx:content/@src') + if not href: + continue + href = item.abshref(urlnormalize(href[0])) + id = ptarget.get('id') + type = ptarget.get('type', 'normal') + klass = ptarget.get('class') + pages.add(name, href, type=type, id=id, klass=klass) + return True + + def _find_page_map(self, opf): + result = xpath(opf, '/o2:package/o2:spine/@page-map') + if result: + id = result[0] + if id not in self.manifest.ids: + return None + item = self.manifest.ids[id] + self.manifest.remove(item) + return item + for item in self.manifest.values(): + if item.media_type == PAGE_MAP_MIME: + self.manifest.remove(item) + return item + return None + + def _pages_from_page_map(self, opf): + item = self._find_page_map(opf) + if item is None: + return False + pmap = item.data + pages = self.pages = PageList() + for page in xpath(pmap, 'o2:page'): + name = page.get('name', '') + href = page.get('href') + if not href: + continue + name = COLLAPSE_RE.sub(' ', name.strip()) + href = item.abshref(urlnormalize(href)) + type = 'normal' + if not name: + type = 'special' + elif name.lower().strip('ivxlcdm') == '': + type = 'front' + pages.add(name, href, type=type) + return True + + def _pages_from_opf(self, opf, item): + if self._pages_from_ncx(opf, item): return + if self._pages_from_page_map(opf): return + self.pages = PageList() + return + def _cover_from_html(self, hcover): with TemporaryDirectory('_html_cover') as tdir: writer = DirWriter() writer.dump(self, tdir) - path = os.path.join(tdir, hcover.href) + path = os.path.join(tdir, urlunquote(hcover.href)) renderer = CoverRenderer(path) data = renderer.image_data id, href = self.manifest.generate('cover', 'cover.jpeg') @@ -1185,8 +1481,10 @@ class OEBBook(object): if self.metadata.cover: id = str(self.metadata.cover[0]) item = self.manifest.ids.get(id, None) - if item is not None: + if item is not None and item.media_type in OEB_IMAGES: return item + else: + self.logger.warn('Invalid cover image @id %r' % id) hcover = self.spine[0] if 'cover' in self.guide: href = self.guide['cover'].href @@ -1224,31 +1522,85 @@ class OEBBook(object): self.metadata.add('cover', cover.id) def _all_from_opf(self, opf): + self.version = opf.get('version', '1.2') self._metadata_from_opf(opf) self._manifest_from_opf(opf) self._spine_from_opf(opf) self._guide_from_opf(opf) - self._toc_from_opf(opf) + item = self._find_ncx(opf) + self._toc_from_opf(opf, item) + self._pages_from_opf(opf, item) self._ensure_cover_image() - + def translate(self, text): lang = str(self.metadata.language[0]) lang = lang.split('-', 1)[0].lower() return translate(lang, text) + def decode(self, data): + if isinstance(data, unicode): + return data + if data[:2] in ('\xff\xfe', '\xfe\xff'): + try: + return data.decode('utf-16') + except UnicodeDecodeError: + pass + try: + return data.decode('utf-8') + except UnicodeDecodeError: + pass + if self.encoding is not None: + try: + return data.decode(self.encoding) + except UnicodeDecodeError: + pass + data, _ = xml_to_unicode(data) + data = data.replace('\r\n', '\n') + data = data.replace('\r', '\n') + return data + def to_opf1(self): package = etree.Element('package', attrib={'unique-identifier': self.uid.id}) - metadata = self.metadata.to_opf1(package) - manifest = self.manifest.to_opf1(package) - spine = self.spine.to_opf1(package) + self.metadata.to_opf1(package) + self.manifest.to_opf1(package) + self.spine.to_opf1(package) tours = element(package, 'tours') tour = element(tours, 'tour', attrib={'id': 'chaptertour', 'title': 'Chapter Tour'}) self.toc.to_opf1(tour) - guide = self.guide.to_opf1(package) + self.guide.to_opf1(package) return {OPF_MIME: ('content.opf', package)} + def _update_playorder(self, ncx): + hrefs = set(xpath(ncx, '//ncx:content/@src')) + playorder = {} + next = 1 + selector = XPath('h:body//*[@id or @name]') + for item in self.spine: + base = item.href + if base in hrefs: + playorder[base] = next + next += 1 + for elem in selector(item.data): + added = False + for attr in ('id', 'name'): + id = elem.get(attr) + if not id: + continue + href = '#'.join([base, id]) + if href in hrefs: + playorder[href] = next + added = True + if added: + next += 1 + selector = XPath('ncx:content/@src') + for elem in xpath(ncx, '//*[@playOrder and ./ncx:content[@src]]'): + href = selector(elem)[0] + order = playorder.get(href, 0) + elem.attrib['playOrder'] = str(order) + return + def _to_ncx(self): lang = unicode(self.metadata.language[0]) ncx = etree.Element(NCX('ncx'), @@ -1256,35 +1608,50 @@ class OEBBook(object): nsmap={None: NCX_NS}) head = etree.SubElement(ncx, NCX('head')) etree.SubElement(head, NCX('meta'), - attrib={'name': 'dtb:uid', 'content': unicode(self.uid)}) + name='dtb:uid', content=unicode(self.uid)) etree.SubElement(head, NCX('meta'), - attrib={'name': 'dtb:depth', 'content': str(self.toc.depth())}) + name='dtb:depth', content=str(self.toc.depth())) + generator = ''.join(['calibre (', calibre.__version__, ')']) etree.SubElement(head, NCX('meta'), - attrib={'name': 'dtb:totalPageCount', 'content': '0'}) + name='dtb:generator', content=generator) etree.SubElement(head, NCX('meta'), - attrib={'name': 'dtb:maxPageNumber', 'content': '0'}) + name='dtb:totalPageCount', content=str(len(self.pages))) + maxpnum = etree.SubElement(head, NCX('meta'), + name='dtb:maxPageNumber', content='0') title = etree.SubElement(ncx, NCX('docTitle')) text = etree.SubElement(title, NCX('text')) text.text = unicode(self.metadata.title[0]) navmap = etree.SubElement(ncx, NCX('navMap')) self.toc.to_ncx(navmap) + if len(self.pages) > 0: + plist = self.pages.to_ncx(ncx) + value = max(int(x) for x in xpath(plist, '//@value')) + maxpnum.attrib['content'] = str(value) + self._update_playorder(ncx) return ncx - def to_opf2(self): + def to_opf2(self, page_map=False): + results = {} package = etree.Element(OPF('package'), attrib={'version': '2.0', 'unique-identifier': self.uid.id}, nsmap={None: OPF2_NS}) - metadata = self.metadata.to_opf2(package) + self.metadata.to_opf2(package) manifest = self.manifest.to_opf2(package) - id, href = self.manifest.generate('ncx', 'toc.ncx') - etree.SubElement(manifest, OPF('item'), - attrib={'id': id, 'href': href, 'media-type': NCX_MIME}) spine = self.spine.to_opf2(package) + self.guide.to_opf2(package) + results[OPF_MIME] = ('content.opf', package) + id, href = self.manifest.generate('ncx', 'toc.ncx') + etree.SubElement(manifest, OPF('item'), id=id, href=href, + attrib={'media-type': NCX_MIME}) spine.attrib['toc'] = id - guide = self.guide.to_opf2(package) - ncx = self._to_ncx() - return {OPF_MIME: ('content.opf', package), - NCX_MIME: (href, ncx)} + results[NCX_MIME] = (href, self._to_ncx()) + if page_map and len(self.pages) > 0: + id, href = self.manifest.generate('page-map', 'page-map.xml') + etree.SubElement(manifest, OPF('item'), id=id, href=href, + attrib={'media-type': PAGE_MAP_MIME}) + spine.attrib['page-map'] = id + results[PAGE_MAP_MIME] = (href, self.pages.to_page_map()) + return results def main(argv=sys.argv): @@ -1292,7 +1659,7 @@ def main(argv=sys.argv): oeb = OEBBook(arg) for name, doc in oeb.to_opf1().values(): print etree.tostring(doc, pretty_print=True) - for name, doc in oeb.to_opf2().values(): + for name, doc in oeb.to_opf2(page_map=True).values(): print etree.tostring(doc, pretty_print=True) return 0 diff --git a/src/calibre/ebooks/oeb/stylizer.py b/src/calibre/ebooks/oeb/stylizer.py index 03a1fade10..e4a0cfd7fe 100644 --- a/src/calibre/ebooks/oeb/stylizer.py +++ b/src/calibre/ebooks/oeb/stylizer.py @@ -109,6 +109,7 @@ class Stylizer(object): STYLESHEETS = {} def __init__(self, tree, path, oeb, profile=PROFILES['PRS505']): + self.oeb = oeb self.profile = profile self.logger = oeb.logger item = oeb.manifest.hrefs[path] @@ -117,7 +118,7 @@ class Stylizer(object): stylesheets = [HTML_CSS_STYLESHEET] head = xpath(tree, '/h:html/h:head')[0] parser = cssutils.CSSParser() - parser.setFetcher(lambda path: ('utf-8', oeb.container.read(path))) + parser.setFetcher(self._fetch_css_file) for elem in head: if elem.tag == XHTML('style') and elem.text \ and elem.get('type', CSS_MIME) in OEB_STYLES: @@ -138,8 +139,7 @@ class Stylizer(object): if path in self.STYLESHEETS: stylesheet = self.STYLESHEETS[path] else: - data = XHTML_CSS_NAMESPACE - data += oeb.manifest.hrefs[path].data + data = self._fetch_css_file(path)[1] stylesheet = parser.parseString(data, href=path) stylesheet.namespaces['h'] = XHTML_NS self.STYLESHEETS[path] = stylesheet @@ -167,6 +167,14 @@ class Stylizer(object): for elem in xpath(tree, '//h:*[@style]'): self.style(elem)._apply_style_attr() + def _fetch_css_file(self, path): + hrefs = self.oeb.manifest.hrefs + if path not in hrefs: + return (None, None) + data = hrefs[path].data + data = XHTML_CSS_NAMESPACE + data + return ('utf-8', data) + def flatten_rule(self, rule, href, index): results = [] if isinstance(rule, CSSStyleRule): diff --git a/src/calibre/ebooks/oeb/transforms/trimmanifest.py b/src/calibre/ebooks/oeb/transforms/trimmanifest.py index 643952c03d..a1d28e5a99 100644 --- a/src/calibre/ebooks/oeb/transforms/trimmanifest.py +++ b/src/calibre/ebooks/oeb/transforms/trimmanifest.py @@ -13,13 +13,9 @@ from urlparse import urldefrag from lxml import etree import cssutils from calibre.ebooks.oeb.base import XPNSMAP, CSS_MIME, OEB_DOCS +from calibre.ebooks.oeb.base import LINK_SELECTORS, CSSURL_RE from calibre.ebooks.oeb.base import urlnormalize -LINK_SELECTORS = [] -for expr in ('//h:link/@href', '//h:img/@src', '//h:object/@data', - '//*/@xl:href'): - LINK_SELECTORS.append(etree.XPath(expr, namespaces=XPNSMAP)) - class ManifestTrimmer(object): def transform(self, oeb, context): oeb.logger.info('Trimming unused files from manifest...') @@ -53,15 +49,13 @@ class ManifestTrimmer(object): if found not in used: new.add(found) elif item.media_type == CSS_MIME: - def replacer(uri): - absuri = item.abshref(urlnormalize(uri)) - if absuri in oeb.manifest.hrefs: + for match in CSSURL_RE.finditer(item.data): + href = match.group('url') + href = item.abshref(urlnormalize(href)) + if href in oeb.manifest.hrefs: found = oeb.manifest.hrefs[href] if found not in used: new.add(found) - return uri - sheet = cssutils.parseString(item.data, href=item.href) - cssutils.replaceUrls(sheet, replacer) used.update(new) unchecked = new for item in oeb.manifest.values(): diff --git a/src/calibre/gui2/dialogs/epub.py b/src/calibre/gui2/dialogs/epub.py index 1e38e4d879..fb8e6bf71e 100644 --- a/src/calibre/gui2/dialogs/epub.py +++ b/src/calibre/gui2/dialogs/epub.py @@ -18,7 +18,7 @@ from calibre.gui2 import error_dialog, choose_images, pixmap_to_data, ResizableD from calibre.ebooks.epub.from_any import SOURCE_FORMATS, config as epubconfig from calibre.ebooks.metadata import MetaInformation from calibre.ptempfile import PersistentTemporaryFile -from calibre.ebooks.metadata.opf import OPFCreator +from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.ebooks.metadata import authors_to_string, string_to_authors @@ -224,6 +224,7 @@ class Config(ResizableDialog, Ui_Dialog): g.setValue(val) elif isinstance(g, (QLineEdit, QTextEdit)): getattr(g, 'setPlainText', g.setText)(val) + getattr(g, 'setCursorPosition', lambda x: x)(0) elif isinstance(g, QComboBox): for value in pref.choices: g.addItem(value) @@ -253,7 +254,8 @@ class Config(ResizableDialog, Ui_Dialog): self.source_format = d.format() def accept(self): - for opt in ('chapter', 'level1_toc', 'level2_toc', 'level3_toc'): + for opt in ('chapter', 'level1_toc', 'level2_toc', 'level3_toc', 'page', + 'page_names'): text = unicode(getattr(self, 'opt_'+opt).text()) if text: try: diff --git a/src/calibre/gui2/dialogs/epub.ui b/src/calibre/gui2/dialogs/epub.ui index d0ff834309..2d5c0fa153 100644 --- a/src/calibre/gui2/dialogs/epub.ui +++ b/src/calibre/gui2/dialogs/epub.ui @@ -493,6 +493,20 @@ </property> </widget> </item> + <item row="7" column="0" > + <widget class="QCheckBox" name="opt_no_justification" > + <property name="text" > + <string>No text &justification</string> + </property> + </widget> + </item> + <item row="8" column="0" > + <widget class="QCheckBox" name="opt_linearize_tables" > + <property name="text" > + <string>&Linearize tables</string> + </property> + </widget> + </item> </layout> </item> <item> @@ -510,7 +524,7 @@ </layout> </widget> <widget class="QWidget" name="pagesetup_page" > - <layout class="QGridLayout" name="_13" > + <layout class="QGridLayout" name="gridLayout_7" > <item row="0" column="0" > <widget class="QLabel" name="profile_label" > <property name="text" > @@ -531,6 +545,32 @@ </property> </widget> </item> + <item row="1" column="0" > + <widget class="QLabel" name="source_profile_label" > + <property name="text" > + <string>&Source profile:</string> + </property> + <property name="buddy" > + <cstring>opt_source_profile</cstring> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QComboBox" name="opt_source_profile" /> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="dest_profile_label" > + <property name="text" > + <string>&Destination profile:</string> + </property> + <property name="buddy" > + <cstring>opt_dest_profile</cstring> + </property> + </widget> + </item> + <item row="2" column="1" > + <widget class="QComboBox" name="opt_dest_profile" /> + </item> <item row="3" column="0" > <widget class="QLabel" name="label_12" > <property name="text" > @@ -630,31 +670,72 @@ </property> </widget> </item> - <item row="1" column="0" > - <widget class="QLabel" name="source_profile_label" > - <property name="text" > - <string>&Source profile:</string> - </property> - <property name="buddy" > - <cstring>opt_source_profile</cstring> + <item row="8" column="0" colspan="2" > + <widget class="QGroupBox" name="page_map_box" > + <property name="title" > + <string>&Page map</string> </property> + <layout class="QGridLayout" name="gridLayout" > + <item rowspan="2" row="0" column="0" colspan="4" > + <widget class="QLabel" name="label_23" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Minimum" hsizetype="Preferred" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string><p>You can control how calibre detects page boundaries using a XPath expression. To learn how to use XPath expressions see the <a href="http://calibre.kovidgoyal.net/user_manual/xpath.html">XPath tutorial</a>. The page boundaries are useful only if you want a mapping from pages in a paper book, to locations in the e-book. This controls where Adobe Digital Editions displays the page numbers in the right margin.</p></string> + </property> + <property name="wordWrap" > + <bool>true</bool> + </property> + <property name="openExternalLinks" > + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QLabel" name="label_21" > + <property name="text" > + <string>&Boundary XPath:</string> + </property> + <property name="buddy" > + <cstring>opt_page</cstring> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QLineEdit" name="opt_page" /> + </item> + <item row="1" column="2" > + <widget class="QLabel" name="label_22" > + <property name="text" > + <string>&Name XPath:</string> + </property> + <property name="buddy" > + <cstring>opt_page_names</cstring> + </property> + </widget> + </item> + <item row="1" column="3" > + <widget class="QLineEdit" name="opt_page_names" /> + </item> + </layout> </widget> </item> - <item row="1" column="1" > - <widget class="QComboBox" name="opt_source_profile" /> - </item> - <item row="2" column="0" > - <widget class="QLabel" name="dest_profile_label" > - <property name="text" > - <string>&Destination profile:</string> + <item row="9" column="0" > + <spacer name="verticalSpacer" > + <property name="orientation" > + <enum>Qt::Vertical</enum> </property> - <property name="buddy" > - <cstring>opt_dest_profile</cstring> + <property name="sizeHint" stdset="0" > + <size> + <width>20</width> + <height>40</height> + </size> </property> - </widget> - </item> - <item row="2" column="1" > - <widget class="QComboBox" name="opt_dest_profile" /> + </spacer> </item> </layout> </widget> @@ -665,28 +746,11 @@ <property name="title" > <string>Automatic &chapter detection</string> </property> - <layout class="QGridLayout" name="gridLayout" > - <item row="1" column="0" > - <widget class="QLabel" name="label_17" > - <property name="text" > - <string>&XPath:</string> - </property> - <property name="buddy" > - <cstring>opt_chapter</cstring> - </property> - </widget> - </item> - <item row="1" column="1" > - <widget class="QLineEdit" name="opt_chapter" /> - </item> - <item row="0" column="0" colspan="2" > + <layout class="QVBoxLayout" name="verticalLayout_4" > + <item> <widget class="QLabel" name="label_8" > <property name="text" > - <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">You can control how calibre detects chapters using a XPath expression. To learn how to use XPath expressions see the <a href="https://calibre.kovidgoyal.net/user_manual/xpath.html"><span style=" text-decoration: underline; color:#0000ff;">XPath tutorial</span></a></p></body></html></string> + <string><p>You can control how calibre detects chapters using a XPath expression. To learn how to use XPath expressions see the <a href="http://calibre.kovidgoyal.net/user_manual/xpath.html">XPath tutorial</a></p></string> </property> <property name="textFormat" > <enum>Qt::RichText</enum> @@ -694,21 +758,41 @@ p, li { white-space: pre-wrap; } <property name="wordWrap" > <bool>true</bool> </property> - </widget> - </item> - <item row="2" column="1" > - <widget class="QComboBox" name="opt_chapter_mark" /> - </item> - <item row="2" column="0" > - <widget class="QLabel" name="label_9" > - <property name="text" > - <string>Chapter &mark:</string> - </property> - <property name="buddy" > - <cstring>opt_chapter_mark</cstring> + <property name="openExternalLinks" > + <bool>true</bool> </property> </widget> </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3" > + <item> + <widget class="QLabel" name="label_17" > + <property name="text" > + <string>&XPath:</string> + </property> + <property name="buddy" > + <cstring>opt_chapter</cstring> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="opt_chapter" /> + </item> + <item> + <widget class="QLabel" name="label_9" > + <property name="text" > + <string>Chapter &mark:</string> + </property> + <property name="buddy" > + <cstring>opt_chapter_mark</cstring> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="opt_chapter_mark" /> + </item> + </layout> + </item> </layout> </widget> </item> @@ -834,7 +918,7 @@ p, li { white-space: pre-wrap; } </property> </widget> </item> - <item row="2" column="0" colspan="2" > + <item row="3" column="0" colspan="2" > <widget class="QDialogButtonBox" name="buttonBox" > <property name="orientation" > <enum>Qt::Horizontal</enum> diff --git a/src/calibre/gui2/dialogs/mobi.py b/src/calibre/gui2/dialogs/mobi.py index 4019950c23..7d0324e0f4 100644 --- a/src/calibre/gui2/dialogs/mobi.py +++ b/src/calibre/gui2/dialogs/mobi.py @@ -17,4 +17,7 @@ class Config(_Config): self.profile_label.setVisible(False) self.opt_profile.setVisible(False) self.opt_dont_split_on_page_breaks.setVisible(False) - self.opt_preserve_tag_structure.setVisible(False) \ No newline at end of file + self.opt_preserve_tag_structure.setVisible(False) + self.opt_linearize_tables.setVisible(False) + self.opt_no_justification.setVisible(False) + self.page_map_box.setVisible(False) \ No newline at end of file diff --git a/src/calibre/gui2/dialogs/recipelistview.py b/src/calibre/gui2/dialogs/recipelistview.py deleted file mode 100644 index 963079307d..0000000000 --- a/src/calibre/gui2/dialogs/recipelistview.py +++ /dev/null @@ -1,16 +0,0 @@ -__license__ = 'GPL v3' -__copyright__ = '2009, John Schember john@nachtimwald.com' -''' -List View for showing recipies. Allows for keyboad events when selecting new -items. -''' - -from PyQt4.Qt import QListView, SIGNAL - -class RecipeListView(QListView): - def __init__(self, *args): - QListView.__init__(self, *args) - - def selectionChanged(self, selected, deselected): - self.emit(SIGNAL('itemChanged(QModelIndex)'), selected.indexes()[0]) - diff --git a/src/calibre/gui2/dialogs/scheduler.py b/src/calibre/gui2/dialogs/scheduler.py index 62dd79ac9b..58e5935b66 100644 --- a/src/calibre/gui2/dialogs/scheduler.py +++ b/src/calibre/gui2/dialogs/scheduler.py @@ -10,8 +10,8 @@ Scheduler for automated recipe downloads import sys, copy, time from datetime import datetime, timedelta, date from PyQt4.Qt import QDialog, QApplication, QLineEdit, QPalette, SIGNAL, QBrush, \ - QColor, QAbstractListModel, Qt, QVariant, QFont, QIcon, \ - QFile, QObject, QTimer, QMutex, QMenu, QAction, QTime + QColor, QAbstractItemModel, Qt, QVariant, QFont, QIcon, \ + QFile, QObject, QTimer, QMutex, QMenu, QAction, QTime, QModelIndex from calibre import english_sort from calibre.gui2.dialogs.scheduler_ui import Ui_Dialog @@ -30,6 +30,7 @@ class Recipe(object): self.id = id self.title = getattr(recipe_class, 'title', None) self.description = getattr(recipe_class, 'description', None) + self.language = getattr(recipe_class, 'language', _('Unknown')) self.last_downloaded = datetime.fromordinal(1) self.downloading = False self.builtin = builtin @@ -86,12 +87,12 @@ def load_recipes(): recipes.append(r) return recipes -class RecipeModel(QAbstractListModel, SearchQueryParser): +class RecipeModel(QAbstractItemModel, SearchQueryParser): LOCATIONS = ['all'] def __init__(self, db, *args): - QAbstractListModel.__init__(self, *args) + QAbstractItemModel.__init__(self, *args) SearchQueryParser.__init__(self) self.default_icon = QIcon(':/images/news.svg') self.custom_icon = QIcon(':/images/user_profile.svg') @@ -99,8 +100,11 @@ class RecipeModel(QAbstractListModel, SearchQueryParser): for x in db.get_recipes(): recipe = compile_recipe(x[1]) self.recipes.append(Recipe(x[0], recipe, False)) - self.refresh() - self._map = list(range(len(self.recipes))) + self.refresh() + self.bold_font = QFont() + self.bold_font.setBold(True) + self.bold_font = QVariant(self.bold_font) + def refresh(self): sr = load_recipes() @@ -110,7 +114,35 @@ class RecipeModel(QAbstractListModel, SearchQueryParser): recipe.last_downloaded = sr[sr.index(recipe)].last_downloaded self.recipes.sort() + self.num_of_recipes = len(self.recipes) + self.category_map = {} + for r in self.recipes: + category = getattr(r, 'language', _('Unknown')) + if not r.builtin: + category = _('Custom') + if r.schedule is not None: + category = _('Scheduled') + if category not in self.category_map.keys(): + self.category_map[category] = [] + self.category_map[category].append(r) + + self.categories = sorted(self.category_map.keys(), cmp=self.sort_categories) + self._map = dict(self.category_map) + + def sort_categories(self, x, y): + + def decorate(x): + if x == _('Scheduled'): + x = '0' + x + elif x == _('Custom'): + x = '1' + x + else: + x = '2' + x + return x + + return cmp(decorate(x), decorate(y)) + def universal_set(self): return set(self.recipes) @@ -129,48 +161,64 @@ class RecipeModel(QAbstractListModel, SearchQueryParser): try: results = self.parse(unicode(query)) except ParseException: - self._map = list(range(len(self.recipes))) + self._map = dict(self.category_map) else: - self._map = [] - for i, recipe in enumerate(self.recipes): - if recipe in results: - self._map.append(i) + self._map = {} + for category in self.categories: + self._map[category] = [] + for recipe in self.category_map[category]: + if recipe in results: + self._map[category].append(recipe) self.reset() def resort(self): self.recipes.sort() self.reset() + + def index(self, row, column, parent): + return self.createIndex(row, column, parent.row() if parent.isValid() else -1) + + def parent(self, index): + if index.internalId() == -1: + return QModelIndex() + return self.createIndex(index.internalId(), 0, -1) + + def columnCount(self, parent): + if not parent.isValid() or not parent.parent().isValid(): + return 1 + return 0 + + def rowCount(self, parent): + if not parent.isValid(): + return len(self.categories) + if not parent.parent().isValid(): + category = self.categories[parent.row()] + return len(self._map[category]) + return 0 - def columnCount(self, *args): - return 1 - - def rowCount(self, *args): - return len(self._map) - def data(self, index, role): - recipe = self.recipes[self._map[index.row()]] - if role == Qt.FontRole: - if recipe.schedule is not None: - font = QFont() - font.setBold(True) - return QVariant(font) - if not recipe.builtin: - font = QFont() - font.setItalic(True) - return QVariant(font) - elif role == Qt.DisplayRole: - return QVariant(recipe.title) - elif role == Qt.UserRole: - return recipe - elif role == Qt.DecorationRole: - icon = self.default_icon - icon_path = (':/images/news/%s.png'%recipe.id).replace('recipe_', '') - if not recipe.builtin: - icon = self.custom_icon - elif QFile().exists(icon_path): - icon = QIcon(icon_path) - return QVariant(icon) - + if index.parent().isValid(): + category = self.categories[index.parent().row()] + recipe = self._map[category][index.row()] + if role == Qt.DisplayRole: + return QVariant(recipe.title) + elif role == Qt.UserRole: + return recipe + elif role == Qt.DecorationRole: + icon = self.default_icon + icon_path = (':/images/news/%s.png'%recipe.id).replace('recipe_', '') + if not recipe.builtin: + icon = self.custom_icon + elif QFile().exists(icon_path): + icon = QIcon(icon_path) + return QVariant(icon) + else: + category = self.categories[index.row()] + if role == Qt.DisplayRole: + num = len(self._map[category]) + return QVariant(category + ' [%d]'%num) + elif role == Qt.FontRole: + return self.bold_font return NONE def update_recipe_schedule(self, recipe): @@ -241,7 +289,7 @@ class SchedulerDialog(QDialog, Ui_Dialog): self._model = RecipeModel(db) self.current_recipe = None self.recipes.setModel(self._model) - self.connect(self.recipes, SIGNAL('itemChanged(QModelIndex)'), self.show_recipe) + self.recipes.currentChanged = self.currentChanged self.connect(self.username, SIGNAL('textEdited(QString)'), self.set_account_info) self.connect(self.password, SIGNAL('textEdited(QString)'), self.set_account_info) self.connect(self.schedule, SIGNAL('stateChanged(int)'), self.do_schedule) @@ -257,10 +305,14 @@ class SchedulerDialog(QDialog, Ui_Dialog): self.connect(self.download, SIGNAL('clicked()'), self.download_now) self.search.setFocus(Qt.OtherFocusReason) self.old_news.setValue(gconf['oldest_news']) - self.rnumber.setText(_('%d recipes')%self._model.rowCount(None)) + self.rnumber.setText(_('%d recipes')%self._model.num_of_recipes) for day in (_('day'), _('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday'), _('Sunday')): self.day.addItem(day) + + def currentChanged(self, current, previous): + if current.parent().isValid(): + self.show_recipe(current) def download_now(self): recipe = self._model.data(self.recipes.currentIndex(), Qt.UserRole) @@ -304,6 +356,7 @@ class SchedulerDialog(QDialog, Ui_Dialog): hour, minute = t.hour(), t.minute() recipe.schedule = encode_schedule(day_of_week, hour, minute) else: + recipe.schedule = None if recipe in recipes: recipes.remove(recipe) save_recipes(recipes) @@ -432,7 +485,7 @@ class Scheduler(QObject): day_matches = day > 6 or day == now.tm_wday tnow = now.tm_hour*60 + now.tm_min matches = day_matches and (hour*60+minute) < tnow - if matches and nowt.toordinal() < date.today().toordinal(): + if matches and recipe.last_downloaded.toordinal() < date.today().toordinal(): needs_downloading.add(recipe) self.debug('Needs downloading:', needs_downloading) @@ -464,7 +517,7 @@ class Scheduler(QObject): recipe = self.recipes[self.recipes.index(recipe)] now = datetime.utcnow() d = now - recipe.last_downloaded - if recipe.schedule is not None: + if recipe.schedule is not None and recipe.schedule < 1e4: interval = timedelta(days=recipe.schedule) if abs(d - interval) < timedelta(hours=1): recipe.last_downloaded += interval @@ -487,7 +540,7 @@ class Scheduler(QObject): if recipe not in self.queue: self.do_download(recipe) finally: - self.lock.unlock() + self.lock.unlock() def refresh_schedule(self, recipes): self.recipes = recipes diff --git a/src/calibre/gui2/dialogs/scheduler.ui b/src/calibre/gui2/dialogs/scheduler.ui index 79ea04977e..808fd0a0d2 100644 --- a/src/calibre/gui2/dialogs/scheduler.ui +++ b/src/calibre/gui2/dialogs/scheduler.ui @@ -24,8 +24,20 @@ </property> <layout class="QVBoxLayout" name="verticalLayout" > <item> - <widget class="RecipeListView" name="recipes" > - <property name="alternatingRowColors" > + <widget class="QTreeView" name="recipes" > + <property name="showDropIndicator" stdset="0" > + <bool>false</bool> + </property> + <property name="iconSize" > + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="animated" > + <bool>true</bool> + </property> + <property name="headerHidden" > <bool>true</bool> </property> </widget> @@ -321,13 +333,6 @@ </item> </layout> </widget> - <customwidgets> - <customwidget> - <class>RecipeListView</class> - <extends>QListView</extends> - <header>recipelistview.h</header> - </customwidget> - </customwidgets> <resources> <include location="../images.qrc" /> </resources> diff --git a/src/calibre/gui2/dialogs/search.ui b/src/calibre/gui2/dialogs/search.ui index f5813c18ee..b35ca84aca 100644 --- a/src/calibre/gui2/dialogs/search.ui +++ b/src/calibre/gui2/dialogs/search.ui @@ -114,6 +114,9 @@ <property name="text" > <string>See the <a href="http://calibre.kovidgoyal.net/user_manual/gui.html#the-search-interface">User Manual</a> for more help</string> </property> + <property name="openExternalLinks" > + <bool>true</bool> + </property> </widget> </item> <item> diff --git a/src/calibre/gui2/images/news/el_mercurio_chile.png b/src/calibre/gui2/images/news/el_mercurio_chile.png new file mode 100644 index 0000000000..1cba7a6aec Binary files /dev/null and b/src/calibre/gui2/images/news/el_mercurio_chile.png differ diff --git a/src/calibre/gui2/images/news/elmundo.png b/src/calibre/gui2/images/news/elmundo.png new file mode 100644 index 0000000000..754b3d0e15 Binary files /dev/null and b/src/calibre/gui2/images/news/elmundo.png differ diff --git a/src/calibre/gui2/images/news/estadao.png b/src/calibre/gui2/images/news/estadao.png new file mode 100644 index 0000000000..8f5637ad58 Binary files /dev/null and b/src/calibre/gui2/images/news/estadao.png differ diff --git a/src/calibre/gui2/images/news/granma.png b/src/calibre/gui2/images/news/granma.png new file mode 100644 index 0000000000..15eaa11fea Binary files /dev/null and b/src/calibre/gui2/images/news/granma.png differ diff --git a/src/calibre/gui2/images/news/jb_online.png b/src/calibre/gui2/images/news/jb_online.png new file mode 100644 index 0000000000..86b4f296e1 Binary files /dev/null and b/src/calibre/gui2/images/news/jb_online.png differ diff --git a/src/calibre/gui2/images/news/la_cuarta.png b/src/calibre/gui2/images/news/la_cuarta.png new file mode 100644 index 0000000000..48a176e908 Binary files /dev/null and b/src/calibre/gui2/images/news/la_cuarta.png differ diff --git a/src/calibre/gui2/images/news/la_tercera.png b/src/calibre/gui2/images/news/la_tercera.png new file mode 100644 index 0000000000..1aa75d7bee Binary files /dev/null and b/src/calibre/gui2/images/news/la_tercera.png differ diff --git a/src/calibre/gui2/images/news/lanacion_chile.png b/src/calibre/gui2/images/news/lanacion_chile.png new file mode 100644 index 0000000000..f6a89ba883 Binary files /dev/null and b/src/calibre/gui2/images/news/lanacion_chile.png differ diff --git a/src/calibre/gui2/images/news/o_globo.png b/src/calibre/gui2/images/news/o_globo.png new file mode 100644 index 0000000000..248a5d4f95 Binary files /dev/null and b/src/calibre/gui2/images/news/o_globo.png differ diff --git a/src/calibre/gui2/images/news/the_oz.png b/src/calibre/gui2/images/news/the_oz.png new file mode 100644 index 0000000000..93f68f9626 Binary files /dev/null and b/src/calibre/gui2/images/news/the_oz.png differ diff --git a/src/calibre/gui2/images/news/vijesti.png b/src/calibre/gui2/images/news/vijesti.png new file mode 100644 index 0000000000..fc2fade6d1 Binary files /dev/null and b/src/calibre/gui2/images/news/vijesti.png differ diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 4f73e685a2..b88842706a 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -115,16 +115,11 @@ class Main(MainWindow, Ui_MainWindow): self.connect(self.donate_action, SIGNAL('triggered(bool)'), self.donate) self.connect(self.restore_action, SIGNAL('triggered(bool)'), lambda c : self.show()) self.connect(self.action_show_book_details, SIGNAL('triggered(bool)'), self.show_book_info) - def restart_app(c): - self.quit(None, restart=True) - self.connect(self.action_restart, SIGNAL('triggered(bool)'), restart_app) - def sta(r): - if r == QSystemTrayIcon.Trigger: - self.hide() if self.isVisible() else self.show() - self.connect(self.system_tray_icon, SIGNAL('activated(QSystemTrayIcon::ActivationReason)'), sta) - def tcme(self, *args): - pass - self.tool_bar.contextMenuEvent = tcme + self.connect(self.action_restart, SIGNAL('triggered(bool)'), + lambda c : self.quit(None, restart=True)) + self.connect(self.system_tray_icon, SIGNAL('activated(QSystemTrayIcon::ActivationReason)'), + self.system_tray_icon_activated) + self.tool_bar.contextMenuEvent = self.no_op ####################### Location View ######################## QObject.connect(self.location_view, SIGNAL('location_selected(PyQt_PyObject)'), self.location_selected) @@ -165,15 +160,11 @@ class Main(MainWindow, Ui_MainWindow): sm.addSeparator() sm.addAction(_('Send to storage card by default')) sm.actions()[-1].setCheckable(True) - def default_sync(checked): - config.set('send_to_storage_card_by_default', bool(checked)) - QObject.disconnect(self.action_sync, SIGNAL("triggered(bool)"), self.sync_to_main_memory) - QObject.disconnect(self.action_sync, SIGNAL("triggered(bool)"), self.sync_to_card) - QObject.connect(self.action_sync, SIGNAL("triggered(bool)"), self.sync_to_card if checked else self.sync_to_main_memory) - QObject.connect(sm.actions()[-1], SIGNAL('toggled(bool)'), default_sync) + QObject.connect(sm.actions()[-1], SIGNAL('toggled(bool)'), + self.do_default_sync) sm.actions()[-1].setChecked(config.get('send_to_storage_card_by_default')) - default_sync(sm.actions()[-1].isChecked()) + self.do_default_sync(sm.actions()[-1].isChecked()) self.sync_menu = sm # Needed md = QMenu() md.addAction(_('Edit metadata individually')) @@ -294,7 +285,7 @@ class Main(MainWindow, Ui_MainWindow): self.stack.setCurrentIndex(0) try: db = LibraryDatabase2(self.library_path) - except OSError, err: + except Exception, err: error_dialog(self, _('Bad database location'), unicode(err)).exec_() dir = unicode(QFileDialog.getExistingDirectory(self, _('Choose a location for your ebook library.'), os.path.expanduser('~'))) @@ -371,6 +362,32 @@ class Main(MainWindow, Ui_MainWindow): self.connect(self.action_news, SIGNAL('triggered(bool)'), self.scheduler.show_dialog) self.location_view.setCurrentIndex(self.location_view.model().index(0)) + def no_op(self, *args): + pass + + def system_tray_icon_activated(self, r): + if r == QSystemTrayIcon.Trigger: + if self.isVisible(): + for window in QApplication.topLevelWidgets(): + if isinstance(window, (MainWindow, QDialog)) and window.isVisible(): + window.hide() + setattr(window, '__systray_minimized', True) + else: + for window in QApplication.topLevelWidgets(): + if getattr(window, '__systray_minimized', False): + window.show() + setattr(window, '__systray_minimized', False) + + + def do_default_sync(self, checked): + config.set('send_to_storage_card_by_default', bool(checked)) + QObject.disconnect(self.action_sync, SIGNAL("triggered(bool)"), + self.sync_to_main_memory) + QObject.disconnect(self.action_sync, SIGNAL("triggered(bool)"), + self.sync_to_card) + QObject.connect(self.action_sync, SIGNAL("triggered(bool)"), + self.sync_to_card if checked else self.sync_to_main_memory) + def change_output_format(self, x): of = unicode(x).strip() if of != prefs['output_format']: @@ -1426,10 +1443,10 @@ class Main(MainWindow, Ui_MainWindow): def donate(self, *args): BUTTON = ''' <form action="https://www.paypal.com/cgi-bin/webscr" method="post"> - <input type="hidden" name="cmd" value="_s-xclick"> - <input type="hidden" name="hosted_button_id" value="1335186"> - <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt=""> - <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1"> + <input type="hidden" name="cmd" value="_s-xclick" /> + <input type="hidden" name="hosted_button_id" value="3029467" /> + <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="Donate to support calibre development" /> + <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /> </form> ''' MSG = _('is the result of the efforts of many volunteers from all over the world. If you find it useful, please consider donating to support its development.') diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 76f244a456..4a2c669a25 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -27,15 +27,6 @@ from calibre.customize.ui import run_plugins_on_import from calibre import sanitize_file_name copyfile = os.link if hasattr(os, 'link') else shutil.copyfile -iscaseinsensitive = iswindows or isosx - -def normpath(x): - # The builtin os.path.normcase doesn't work on OS X - x = os.path.abspath(x) - if iscaseinsensitive: - x = x.lower() - return x - FIELD_MAP = {'id':0, 'title':1, 'authors':2, 'publisher':3, 'rating':4, 'timestamp':5, 'size':6, 'tags':7, 'comments':8, 'series':9, 'series_index':10, @@ -355,6 +346,8 @@ class LibraryDatabase2(LibraryDatabase): if isinstance(self.dbpath, unicode): self.dbpath = self.dbpath.encode(filesystem_encoding) self.connect() + self.is_case_sensitive = not iswindows and not isosx and \ + not os.path.exists(self.dbpath.replace('metadata.db', 'MeTAdAtA.dB')) # Upgrade database while True: meth = getattr(self, 'upgrade_version_%d'%self.user_version, None) @@ -488,6 +481,16 @@ class LibraryDatabase2(LibraryDatabase): name = title + ' - ' + author return name + def rmtree(self, path): + if not self.normpath(self.library_path).startswith(self.normpath(path)): + shutil.rmtree(path) + + def normpath(self, path): + path = os.path.abspath(os.path.realpath(path)) + if not self.is_case_sensitive: + path = path.lower() + return path + def set_path(self, index, index_is_id=False): ''' Set the path to the directory containing this books files based on its @@ -531,11 +534,11 @@ class LibraryDatabase2(LibraryDatabase): self.data.set(id, FIELD_MAP['path'], path, row_is_id=True) # Delete not needed directories if current_path and os.path.exists(spath): - if normpath(spath) != normpath(tpath): - shutil.rmtree(spath) + if self.normpath(spath) != self.normpath(tpath): + self.rmtree(spath) parent = os.path.dirname(spath) if len(os.listdir(parent)) == 0: - shutil.rmtree(parent) + self.rmtree(parent) def add_listener(self, listener): ''' @@ -698,10 +701,10 @@ class LibraryDatabase2(LibraryDatabase): path = os.path.join(self.library_path, self.path(id, index_is_id=True)) self.data.remove(id) if os.path.exists(path): - shutil.rmtree(path) + self.rmtree(path) parent = os.path.dirname(path) if len(os.listdir(parent)) == 0: - shutil.rmtree(parent) + self.rmtree(parent) self.conn.execute('DELETE FROM books WHERE id=?', (id,)) self.conn.commit() self.clean() diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index f587a0122a..b5ec52dd7c 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -102,7 +102,7 @@ Device Integration What devices does |app| support? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -At the moment |app| has full support for the SONY PRS 500/505/700, Cybook Gen 3 as well as the iPhone. In addition, using the :guilabel:`Save to disk` function you can use it with any ebook reader that exports itself as a USB disk. +At the moment |app| has full support for the SONY PRS 500/505/700, Cybook Gen 3, Amazon Kindle as well as the iPhone. In addition, using the :guilabel:`Save to disk` function you can use it with any ebook reader that exports itself as a USB disk. I used |app| to transfer some books to my reader, and now the SONY software hangs every time I connect the reader? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/calibre/parallel.py b/src/calibre/parallel.py index a1a439d579..f9b4513c78 100644 --- a/src/calibre/parallel.py +++ b/src/calibre/parallel.py @@ -161,7 +161,7 @@ class WorkerMother(object): self.executable = self.gui_executable = sys.executable self.prefix = '' if isfrozen: - fd = getattr(sys, 'frameworks_dir') + fd = os.path.realpath(getattr(sys, 'frameworks_dir')) contents = os.path.dirname(fd) self.gui_executable = os.path.join(contents, 'MacOS', os.path.basename(sys.executable)) diff --git a/src/calibre/trac/donations/server.py b/src/calibre/trac/donations/server.py index c3e0337290..0141c6a317 100644 --- a/src/calibre/trac/donations/server.py +++ b/src/calibre/trac/donations/server.py @@ -196,7 +196,7 @@ class Server(object): def calculate_month_trend(self, days=31): stats = self.get_slice(date.today()-timedelta(days=days-1), date.today()) - fig = plt.figure(2, (8, 3), 96)#, facecolor, edgecolor, frameon, FigureClass) + fig = plt.figure(2, (12, 4), 96)#, facecolor, edgecolor, frameon, FigureClass) ax = fig.add_subplot(111) x = list(range(days-1, -1, -1)) y = stats.daily_totals @@ -205,6 +205,17 @@ class Server(object): ax.set_ylabel('Income ($)') ax.hlines([stats.daily_average], 0, days-1) ax.set_xlim([0, days-1]) + text = u'''\ +Total: $%(total).2f +Daily average: $%(da).2f \u00b1 %(dd).2f +Average contribution: $%(ac).2f \u00b1 %(ad).2f +Donors per day: %(dpd).2f + '''%dict(total=stats.total, da=stats.daily_average, + dd=stats.daily_deviation, ac=stats.average, + ad=stats.average_deviation, + dpd=len(stats.totals)/float(stats.period.days), + ) + text = ax.annotate(text, (0.6, 0.65), textcoords='axes fraction') fig.savefig(self.MONTH_TRENDS) def calculate_trend(self): @@ -223,7 +234,7 @@ class Server(object): x = [m.min for m in _months] y = [m.total for m in _months] ml = mdates.MonthLocator() # every month - fig = plt.figure(1, (8, 3), 96)#, facecolor, edgecolor, frameon, FigureClass) + fig = plt.figure(1, (8, 4), 96)#, facecolor, edgecolor, frameon, FigureClass) ax = fig.add_subplot(111) ax.bar(x, y, align='center', width=20, color='g') ax.xaxis.set_major_locator(ml) diff --git a/src/calibre/trac/plugins/templates/binary.html b/src/calibre/trac/plugins/templates/binary.html index cd67bf41f2..7361e37014 100644 --- a/src/calibre/trac/plugins/templates/binary.html +++ b/src/calibre/trac/plugins/templates/binary.html @@ -23,15 +23,14 @@ While you wait for the download to complete, please consider donating to support the development of ${app}. <div> - <form action="https://www.paypal.com/cgi-bin/webscr" method="post"> + <form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input type="hidden" name="cmd" value="_s-xclick" /> - <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" /> + <input type="hidden" name="hosted_button_id" value="3029289" /> + <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="Donate to support calibre development" /> <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /> - <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHbwYJKoZIhvcNAQcEoIIHYDCCB1wCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYBn7jneGiSLVO8rcDrBtOUXL+HftY+CiC47hTntwICio6qqpLKezIryyG8tKcjY58Rcocur/kDwljEutIafVG7XRA7BJL9eZdHAZsZdX04f4dApzkWwR9w6GQhj0kwmO2ZNE878UcgGZBve4qQKWM8bf2pMY7vJwCNoo6ozpIi3VTELMAkGBSsOAwIaBQAwgewGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIBTALt7s1gJmAgcjEAwUMRYeIdIOE/yi0Y5vrVKBFxOUCbqTx/lu3Rk4EHsODZXLHT+BDA5WSWYO3AXfv2Lmlv1kJ7jWrjUVirYoQ5M4qdIhY9DtvPioIMMRoTJmYM9JKH8n2TWcjJ1XIzIuDP4zn8/Ya9hap3RHOrj2RBj89g7iSuFRsjoA0PYZgtWAKwR7g3LLpjRachn041JO55BEd3YWUgorNQeo3WEHgowLFfTWgFFePkm8OoWA1klWkYp4S07IhX5NaRc8OegkdshpkiIHGAKCCA4cwggODMIIC7KADAgECAgEAMA0GCSqGSIb3DQEBBQUAMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTAeFw0wNDAyMTMxMDEzMTVaFw0zNTAyMTMxMDEzMTVaMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwUdO3fxEzEtcnI7ZKZL412XvZPugoni7i7D7prCe0AtaHTc97CYgm7NsAtJyxNLixmhLV8pyIEaiHXWAh8fPKW+R017+EmXrr9EaquPmsVvTywAAE1PMNOKqo2kl4Gxiz9zZqIajOm1fZGWcGS0f5JQ2kBqNbvbg2/Za+GJ/qwUCAwEAAaOB7jCB6zAdBgNVHQ4EFgQUlp98u8ZvF71ZP1LXChvsENZklGswgbsGA1UdIwSBszCBsIAUlp98u8ZvF71ZP1LXChvsENZklGuhgZSkgZEwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAgV86VpqAWuXvX6Oro4qJ1tYVIT5DgWpE692Ag422H7yRIr/9j/iKG4Thia/Oflx4TdL+IFJBAyPK9v6zZNZtBgPBynXb048hsP16l2vi0k5Q2JKiPDsEfBhGI+HnxLXEaUWAcVfCsQFvd2A1sxRr67ip5y2wwBelUecP3AjJ+YcxggGaMIIBlgIBATCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTA4MDQzMDE1MzkyMlowIwYJKoZIhvcNAQkEMRYEFJSI9/zWx7TUlKPY7kLjnvzB1h6sMA0GCSqGSIb3DQEBAQUABIGAikZNCmQdkWPdfmYnGqOb1f65ViaK0zjHf50azvsigWQLlhHqJ3PgB+jEJH3JU9Pm9M4wgiK23Bg2oIGuIsAfQkYO9mw/HjtDtOQHqXyZZbrM32YGtNWUD4ynakLYnaz7OnPl40aTPD4iDApgsGcj1oMdmw7KA2E9J0l2J9iJXF4=-----END PKCS7-----" /> - </form> - - </div> - <br /> + </form> + <br /> + </div> <h2>Note</h2> <div class="note">$note</div> diff --git a/src/calibre/trac/plugins/templates/distro.html b/src/calibre/trac/plugins/templates/distro.html index 09856c35be..e735c6f4ad 100644 --- a/src/calibre/trac/plugins/templates/distro.html +++ b/src/calibre/trac/plugins/templates/distro.html @@ -57,11 +57,11 @@ python setup.py build && sudo python setup.py install While you wait for the installation to complete, please consider donating to support the development of ${distro.app}. <div> <form action="https://www.paypal.com/cgi-bin/webscr" method="post"> - <input type="hidden" name="cmd" value="_s-xclick" /> - <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" /> - <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /> - <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHbwYJKoZIhvcNAQcEoIIHYDCCB1wCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYBn7jneGiSLVO8rcDrBtOUXL+HftY+CiC47hTntwICio6qqpLKezIryyG8tKcjY58Rcocur/kDwljEutIafVG7XRA7BJL9eZdHAZsZdX04f4dApzkWwR9w6GQhj0kwmO2ZNE878UcgGZBve4qQKWM8bf2pMY7vJwCNoo6ozpIi3VTELMAkGBSsOAwIaBQAwgewGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIBTALt7s1gJmAgcjEAwUMRYeIdIOE/yi0Y5vrVKBFxOUCbqTx/lu3Rk4EHsODZXLHT+BDA5WSWYO3AXfv2Lmlv1kJ7jWrjUVirYoQ5M4qdIhY9DtvPioIMMRoTJmYM9JKH8n2TWcjJ1XIzIuDP4zn8/Ya9hap3RHOrj2RBj89g7iSuFRsjoA0PYZgtWAKwR7g3LLpjRachn041JO55BEd3YWUgorNQeo3WEHgowLFfTWgFFePkm8OoWA1klWkYp4S07IhX5NaRc8OegkdshpkiIHGAKCCA4cwggODMIIC7KADAgECAgEAMA0GCSqGSIb3DQEBBQUAMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTAeFw0wNDAyMTMxMDEzMTVaFw0zNTAyMTMxMDEzMTVaMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwUdO3fxEzEtcnI7ZKZL412XvZPugoni7i7D7prCe0AtaHTc97CYgm7NsAtJyxNLixmhLV8pyIEaiHXWAh8fPKW+R017+EmXrr9EaquPmsVvTywAAE1PMNOKqo2kl4Gxiz9zZqIajOm1fZGWcGS0f5JQ2kBqNbvbg2/Za+GJ/qwUCAwEAAaOB7jCB6zAdBgNVHQ4EFgQUlp98u8ZvF71ZP1LXChvsENZklGswgbsGA1UdIwSBszCBsIAUlp98u8ZvF71ZP1LXChvsENZklGuhgZSkgZEwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAgV86VpqAWuXvX6Oro4qJ1tYVIT5DgWpE692Ag422H7yRIr/9j/iKG4Thia/Oflx4TdL+IFJBAyPK9v6zZNZtBgPBynXb048hsP16l2vi0k5Q2JKiPDsEfBhGI+HnxLXEaUWAcVfCsQFvd2A1sxRr67ip5y2wwBelUecP3AjJ+YcxggGaMIIBlgIBATCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTA4MDQzMDE1MzkyMlowIwYJKoZIhvcNAQkEMRYEFJSI9/zWx7TUlKPY7kLjnvzB1h6sMA0GCSqGSIb3DQEBAQUABIGAikZNCmQdkWPdfmYnGqOb1f65ViaK0zjHf50azvsigWQLlhHqJ3PgB+jEJH3JU9Pm9M4wgiK23Bg2oIGuIsAfQkYO9mw/HjtDtOQHqXyZZbrM32YGtNWUD4ynakLYnaz7OnPl40aTPD4iDApgsGcj1oMdmw7KA2E9J0l2J9iJXF4=-----END PKCS7-----" /> - </form> + <input type="hidden" name="cmd" value="_s-xclick" /> + <input type="hidden" name="hosted_button_id" value="3029289" /> + <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="Donate to support calibre development" /> + <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /> + </form> </div> </div> </body> diff --git a/src/calibre/translations/ar.po b/src/calibre/translations/ar.po new file mode 100644 index 0000000000..f615c21206 --- /dev/null +++ b/src/calibre/translations/ar.po @@ -0,0 +1,5427 @@ +# Arabic translation for calibre +# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 +# This file is distributed under the same license as the calibre package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: calibre\n" +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" +"POT-Creation-Date: 2009-01-27 01:54+0000\n" +"PO-Revision-Date: 2009-02-04 10:04+0000\n" +"Last-Translator: Abdellah Chelli <sneetsher@gmail.com>\n" +"Language-Team: Arabic <ar@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 +msgid "Does absolutely nothing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:44 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:497 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:989 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:77 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:79 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:81 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:95 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:97 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:99 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:101 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:69 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:70 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:199 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:229 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:232 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:277 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:45 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:47 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:87 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:89 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:145 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:334 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:449 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:820 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:12 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:36 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:66 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:477 +#: /home/kovid/work/calibre/src/calibre/ebooks/odt/to_oeb.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:361 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:366 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:858 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:861 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:53 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:376 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:899 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:700 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:942 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:945 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:61 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:123 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:257 +#: /home/kovid/work/calibre/src/calibre/library/database.py:920 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1405 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1434 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1468 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1594 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:473 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:485 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:828 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:861 +msgid "Unknown" +msgstr "مجهول" + +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:62 +msgid "Base" +msgstr "أساس" + +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:148 +msgid "File type" +msgstr "نوع الملف" + +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:182 +msgid "Metadata reader" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:209 +msgid "Metadata writer" +msgstr "كاتب البيانات الوصفية" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:12 +msgid "" +"Follow all local links in an HTML file and create a ZIP file containing all " +"linked files. This plugin is run every time you add an HTML file to the " +"library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:32 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:43 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:53 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:64 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:74 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:84 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:94 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:105 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:116 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:126 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:136 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:146 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:156 +msgid "Read metadata from %s files" +msgstr "إقرأ البيانات الوصفية من الملفات %s" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:166 +msgid "Extract cover from comic files" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:186 +msgid "Read metadata from ebooks in ZIP archives" +msgstr "إقرأ البيانات الوصفية من كتب إلكترونية في محفوظات ZIP" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:196 +msgid "Read metadata from ebooks in RAR archives" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:207 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:217 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:227 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:237 +msgid "Set metadata in %s files" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:28 +msgid "Installed plugins" +msgstr "ملحقات مثبتة" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:29 +msgid "Mapping for filetype plugins" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:30 +msgid "Local plugin customization" +msgstr "تخصيص ملحقات محلية" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:31 +msgid "Disabled plugins" +msgstr "ملحقات معطلة" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:66 +msgid "No valid plugin found in " +msgstr "لم يعثر على أي ملحق صالح في " + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:184 +msgid "Initialization of plugin %s failed with traceback:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:261 +msgid "" +" %prog options\n" +" \n" +" Customize calibre by loading external plugins.\n" +" " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:267 +msgid "Add a plugin by specifying the path to the zip file containing it." +msgstr "أضف ملحقا بتعيين المسار إلى ملف zip الذي يحتويه." + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:269 +msgid "Remove a custom plugin by name. Has no effect on builtin plugins" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:271 +msgid "" +"Customize plugin. Specify name of plugin and customization string separated " +"by a comma." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:273 +msgid "List all installed plugins" +msgstr "أسرد كل الملحقات المثبتة" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:275 +msgid "Enable the named plugin" +msgstr "شغل الملحق المسمى" + +#: /home/kovid/work/calibre/src/calibre/customize/ui.py:277 +msgid "Disable the named plugin" +msgstr "عطل الملحق المسمى" + +#: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:41 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:384 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:70 +msgid "The reader has no storage card connected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:60 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:89 +msgid "There is insufficient free space on the storage card" +msgstr "لا توجد مساحة كافية في بطاقة التخزين" + +#: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:62 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:91 +msgid "There is insufficient free space in main memory" +msgstr "لا توجد مساحة كافية في الذاكرة الرئيسية" + +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:140 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:167 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:195 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:191 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:227 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:254 +msgid "Unable to detect the %s disk drive. Try rebooting." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:94 +msgid "Options to control the conversion to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +msgid "" +"The output EPUB file. If not specified, it is derived from the input file " +"name." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:107 +msgid "" +"Profile of the target device this EPUB is meant for. Set to None to create a " +"device independent EPUB. The profile is used for device specific " +"restrictions on the EPUB. Choices are: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:109 +msgid "" +"Either the path to a CSS stylesheet or raw CSS. This CSS will override any " +"existing CSS declarations in the source files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +msgid "Control auto-detection of document structure." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +msgid "" +"An XPath expression to detect chapter titles. The default is to consider " +"<h1> or\n" +"<h2> tags that contain the words \"chapter\",\"book\",\"section\" or " +"\"part\" as chapter titles as \n" +"well as any tags that have class=\"chapter\". \n" +"The expression used must evaluate to a list of elements. To disable chapter " +"detection,\n" +"use the expression \"/\". See the XPath Tutorial in the calibre User Manual " +"for further\n" +"help on using this feature.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:121 +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 "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:123 +msgid "Path to the cover to be used for this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:126 +msgid "" +"Use the cover detected from the source file in preference to the specified " +"cover." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:128 +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 "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:130 +msgid "" +"Control the automatic generation of a Table of Contents. If an OPF file is " +"detected\n" +"and it specifies a Table of Contents, then that will be used rather than " +"trying\n" +"to auto-generate a Table of Contents.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:136 +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 --toc-" +"threshold number of chapters were detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:138 +msgid "Don't add auto-detected chapters to the Table of Contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:140 +msgid "" +"If fewer than this number of chapters is detected, then links are added to " +"the Table of Contents. Default: %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:142 +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 "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:144 +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 "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:146 +msgid "" +"Path to a .ncx file that contains the table of contents to use for this " +"ebook. The NCX file should contain links relative to the directory it is " +"placed in. See http://www.niso.org/workrooms/daisy/Z39-86-2005.html#NCX for " +"an overview of the NCX format." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:148 +msgid "" +"Normally, if the source file already has a Table of Contents, it is used in " +"preference to the autodetected one. With this option, the autodetected one " +"is always used." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:150 +msgid "Control page layout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:152 +msgid "Set the top margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:154 +msgid "Set the bottom margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:156 +msgid "Set the left margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:158 +msgid "Set the right margin in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:160 +msgid "" +"The base font size in pts. Default is %defaultpt. Set to 0 to disable " +"rescaling of fonts." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:162 +msgid "" +"Remove spacing between paragraphs. Will not work if the source file forces " +"inter-paragraph spacing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:164 +msgid "" +"Preserve the HTML tag structure while splitting large HTML files. This is " +"only neccessary if the HTML files contain CSS that uses sibling selectors. " +"Enabling this greatly slows down processing of large HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:167 +msgid "Print generated OPF file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:169 +msgid "Print generated NCX file to stdout" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:171 +msgid "Keep intermediate files during processing by html2epub" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:173 +msgid "" +"Extract the contents of the produced EPUB file to the specified directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:184 +msgid "" +"%%prog [options] filename\n" +"\n" +"Convert any of a large number of ebook formats to a %s file. Supported " +"formats are: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:102 +msgid "Could not find an ebook inside the archive" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:214 +msgid "" +"%prog [options] file.html|opf\n" +"\n" +"Convert a HTML file to an EPUB ebook. Recursively follows links in the HTML " +"file.\n" +"If you specify an OPF file instead of an HTML file, the list of links is " +"takes from\n" +"the <spine> element of the OPF file. \n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:465 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:746 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:589 +msgid "Output written to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:487 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1087 +msgid "You must specify an input HTML file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/iterator.py:36 +msgid "%s format books are not supported" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:30 +msgid "" +"Could not find reasonable point at which to split: %s Sub-tree size: %d KB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:142 +msgid "" +"\t\tToo much markup. Re-splitting without structure preservation. This may " +"cause incorrect rendering." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:509 +msgid "Written processed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:872 +msgid "Options to control the traversal of HTML" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:879 +msgid "The output directory. Default is the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:881 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:537 +msgid "Character encoding for HTML files. Default is to auto detect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:883 +msgid "" +"Create the output in a zip file. If this option is specified, the --output " +"should be the name of a file not a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:885 +msgid "Control the following of links in HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:887 +msgid "" +"Traverse links in HTML files breadth first. Normally, they are traversed " +"depth first" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:889 +msgid "" +"Maximum levels of recursion when following links in HTML files. Must be non-" +"negative. 0 implies that no links in the root HTML file are followed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:891 +msgid "Set metadata of the generated ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:893 +msgid "Set the title. Default is to autodetect." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:895 +msgid "The author(s) of the ebook, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:897 +msgid "The subject(s) of this book, as a comma separated list." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:899 +msgid "Set the publisher of this book." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:901 +msgid "A summary of this book." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:903 +msgid "Load metadata from the specified OPF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:905 +msgid "Options useful for debugging" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:907 +msgid "" +"Be more verbose while processing. Can be specified multiple times to " +"increase verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:909 +msgid "Output HTML is \"pretty printed\" for easier parsing by humans" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:915 +msgid "" +"%prog [options] file.html|opf\n" +"\n" +"Follow all links in an HTML file and collect them into the specified " +"directory.\n" +"Also collects any resources like images, stylesheets, scripts, etc. \n" +"If an OPF file is specified instead, the list of files in its <spine> " +"element\n" +"is used.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/from_any.py:47 +msgid "Creating LIT file from EPUB..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:852 +msgid "%prog [options] LITFILE" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:855 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:501 +msgid "Output directory. Defaults to current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:858 +msgid "Legibly format extracted markup. May modify meaningful whitespace." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:861 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:719 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:549 +msgid "Useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:872 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:525 +msgid "OEB ebook created in" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:713 +msgid "%prog [options] OPFFILE" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:716 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/from_feeds.py:26 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:546 +msgid "Output file. Default is derived from input filename." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:74 +msgid "Set the title. Default: filename." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:76 +msgid "" +"Set the author(s). Multiple authors should be set as a comma separated list. " +"Default: %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:79 +msgid "Set the comment." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:81 +msgid "Set the category" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:83 +msgid "Sort key for the title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:85 +msgid "Sort key for the author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:87 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:108 +msgid "Publisher" +msgstr "ناشر" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:89 +msgid "Path to file containing image to be used as cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:91 +msgid "" +"If there is a cover graphic detected in the source file, use that instead of " +"the specified cover." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:94 +msgid "Output file name. Default is derived from input filename" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +msgid "" +"Render HTML tables as blocks of text instead of actual tables. This is " +"neccessary if the HTML contains very large or complex tables." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:99 +msgid "" +"Specify the base font size in pts. All fonts are rescaled accordingly. This " +"option obsoletes the --font-delta option and takes precedence over it. To " +"use --font-delta, set this to 0. Default: %defaultpt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:101 +msgid "Enable autorotation of images that are wider than the screen width." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:104 +msgid "Set the space between words in pts. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:106 +msgid "Separate paragraphs by blank lines." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:108 +msgid "Add a header to all the pages with title and author." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:110 +msgid "" +"Set the format of the header. %a is replaced by the author and %t by the " +"title. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:112 +msgid "Add extra spacing below the header. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:114 +msgid "" +"Override the CSS. Can be either a path to a CSS stylesheet or a string. If " +"it is a string it is interpreted as CSS." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:116 +msgid "" +"Use the <spine> element from the OPF file to determine the order in which " +"the HTML files are appended to the LRF. The .opf file must be in the same " +"directory as the base HTML file." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:118 +msgid "" +"Minimum paragraph indent (the indent of the first line of a paragraph) in " +"pts. Default: %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:120 +msgid "" +"Increase the font size by 2 * FONT_DELTA pts and the line spacing by " +"FONT_DELTA pts. FONT_DELTA can be a fraction.If FONT_DELTA is negative, the " +"font size is decreased." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:125 +msgid "" +"Render all content as black on white instead of the colors specified by the " +"HTML or CSS." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:131 +msgid "" +"Profile of the target device for which this LRF is being generated. The " +"profile determines things like the resolution and screen size of the target " +"device. Default: %s Supported profiles: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:137 +msgid "Left margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:139 +msgid "Right margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:141 +msgid "Top margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:143 +msgid "Bottom margin of page. Default is %default px." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:145 +msgid "" +"Render tables in the HTML as images (useful if the document has large or " +"complex tables)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:147 +msgid "" +"Multiply the size of text in rendered tables by this factor. Default is " +"%default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:152 +msgid "" +"The maximum number of levels to recursively process links. A value of 0 " +"means thats links are not followed. A negative value means that <a> tags are " +"ignored." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:156 +msgid "" +"A regular expression. <a> tags whose href matches will be ignored. Defaults " +"to %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:160 +msgid "Don't add links to the table of contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:164 +msgid "Prevent the automatic detection chapters." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 +msgid "" +"The regular expression used to detect chapter titles. It is searched for in " +"heading tags (h1-h6). Defaults to %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:170 +msgid "" +"Detect a chapter beginning at an element having the specified attribute. The " +"format for this option is tagname regexp,attribute name,attribute value " +"regexp. For example to match all heading tags that have the attribute " +"class=\"chapter\" you would use \"h\\d,class,chapter\". You can set the " +"attribute to \"none\" to match only on tag names. So for example, to match " +"all h2 tags, you would use \"h2,none,\". Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:172 +msgid "" +"If html2lrf does not find any page breaks in the html file and cannot detect " +"chapter headings, it will automatically insert page-breaks before the tags " +"whose names match this regular expression. Defaults to %default. You can " +"disable it by setting the regexp to \"$\". The purpose of this option is to " +"try to ensure that there are no really long pages as this degrades the page " +"turn performance of the LRF. Thus this option is ignored if the current page " +"has only a few elements." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 +msgid "" +"Force a page break before tags whose names match this regular expression." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:184 +msgid "" +"Force a page break before an element having the specified attribute. The " +"format for this option is tagname regexp,attribute name,attribute value " +"regexp. For example to match all heading tags that have the attribute " +"class=\"chapter\" you would use \"h\\d,class,chapter\". Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:187 +msgid "Add detected chapters to the table of contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:190 +msgid "Preprocess Baen HTML files to improve generated LRF." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192 +msgid "" +"You must add this option if processing files generated by pdftohtml, " +"otherwise conversion will fail." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:194 +msgid "Use this option on html0 files from Book Designer." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:197 +msgid "" +"Specify trutype font families for serif, sans-serif and monospace fonts. " +"These fonts will be embedded in the LRF file. Note that custom fonts lead to " +"slower page turns. For example: --serif-family \"Times New Roman\"\n" +" " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:205 +msgid "The serif family of fonts to embed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:208 +msgid "The sans-serif family of fonts to embed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:211 +msgid "The monospace family of fonts to embed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:215 +msgid "Be verbose while processing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:217 +msgid "Convert to LRS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:219 +msgid "" +"Minimize memory usage at the cost of longer processing times. Use this " +"option if you are on a memory constrained machine." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:221 +msgid "" +"Specify the character encoding of the source file. If the output LRF file " +"contains strange characters, try changing this option. A common encoding for " +"files from windows computers is cp-1252. Another common choice is utf-8. The " +"default is to try and guess the encoding." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:164 +msgid "Converting from %s to LRF is not supported." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:175 +msgid "" +"any2lrf [options] myfile\n" +"\n" +"Convert any ebook format into LRF. Supported formats are:\n" +"LIT, RTF, TXT, HTML, EPUB, MOBI, PRC and PDF. any2lrf will also process a " +"RAR or\n" +"ZIP archive, looking for an ebook inside the archive.\n" +" " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:190 +msgid "No file to convert specified." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:224 +msgid "Rendered %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:227 +msgid "Failed %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:279 +msgid "" +"Failed to process comic: %s\n" +"\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 +msgid "" +"Options to control the conversion of comics (CBR, CBZ) files into ebooks" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:292 +msgid "Title for generated ebook. Default is to use the filename." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:294 +msgid "" +"Set the author in the metadata of the generated ebook. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:22 +msgid "" +"Path to output file. By default a file is created in the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 +msgid "Number of colors for grayscale image conversion. Default: %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 +msgid "" +"Disable normalize (improve contrast) color range for pictures. Default: False" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:303 +msgid "Maintain picture aspect ratio. Default is to fill the screen." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:305 +msgid "Disable sharpening." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 +msgid "Don't split landscape images into two portrait images" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 +msgid "" +"Keep aspect ratio and scale image using screen height as image width for " +"viewing in landscape mode." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 +msgid "" +"Used for right-to-left publications like manga. Causes landscape pages to be " +"split into portrait pages from right to left." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 +msgid "" +"Enable Despeckle. Reduces speckle noise. May greatly increase processing " +"time." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:315 +msgid "" +"Don't sort the files found in the comic alphabetically by name. Instead use " +"the order they were added to the comic." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:317 +msgid "" +"Choose a profile for the device you are generating this file for. The " +"default is the SONY PRS-500 with a screen size of 584x754 pixels. This is " +"suitable for any reader with the same screen size. Choices are %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:319 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:20 +msgid "" +"Be verbose, useful for debugging. Can be specified multiple times for " +"greater verbosity." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:321 +msgid "Don't show progress bar." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:324 +msgid "Apply no processing to the image" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:329 +msgid "" +"%prog [options] comic.cb[z|r]\n" +"\n" +"Convert a comic in a CBZ or CBR file to an ebook. \n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:389 +msgid "Output written to" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:549 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/from_comic.py:35 +msgid "Rendering comic pages..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/epub/convert_from.py:17 +msgid "" +"Usage: %prog [options] mybook.epub\n" +" \n" +" \n" +"%prog converts mybook.epub to mybook.lrf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 +msgid "" +"%prog [options] mybook.fb2\n" +"\n" +"\n" +"%prog converts mybook.fb2 to mybook.lrf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:28 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:24 +msgid "Print generated HTML to stdout and quit." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:30 +msgid "Keep generated HTML files after completing conversion to LRF." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 +msgid "Options to control the behavior of feeds2disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 +msgid "Options to control the behavior of html2lrf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:44 +msgid "Fetching of recipe failed: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:317 +msgid "\tBook Designer file detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:319 +msgid "\tParsing HTML..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:342 +msgid "\tBaen file detected. Re-parsing..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:358 +msgid "Written preprocessed HTML to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:376 +msgid "Processing %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:390 +msgid "\tConverting to BBeB..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:536 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:549 +msgid "Could not parse file: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:541 +msgid "%s is an empty file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:561 +msgid "Failed to parse link %s %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:605 +msgid "Cannot add link %s to TOC" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:957 +msgid "Unable to process image %s. Error: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:995 +msgid "Unable to process interlaced PNG %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1010 +msgid "" +"Could not process image: %s\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1763 +msgid "" +"An error occurred while processing a table: %s. Ignoring table markup." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1765 +msgid "" +"Bad table:\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1787 +msgid "Table has cell that is too large" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1817 +msgid "" +"You have to save the website %s as an html file first and then run html2lrf " +"on it." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1860 +msgid "Could not read cover image: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1863 +msgid "Cannot read from: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1988 +msgid "Failed to process opf file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1994 +msgid "" +"Usage: %prog [options] mybook.html\n" +"\n" +"\n" +"%prog converts mybook.html to mybook.lrf. \n" +"%prog follows all links in mybook.html that point \n" +"to local files recursively. Thus, you can use it to \n" +"convert a whole tree of HTML files." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 +msgid "" +"Usage: %prog [options] mybook.lit\n" +"\n" +"\n" +"%prog converts mybook.lit to mybook.lrf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:136 +msgid "" +"%prog book.lrf\n" +"Convert an LRF file into an LRS (XML UTF-8 encoded) file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:137 +msgid "Output LRS file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:139 +msgid "Do not save embedded image and font files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:158 +msgid "Parsing LRF..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:161 +msgid "Creating XML..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:163 +msgid "LRS written to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:249 +msgid "Could not read from thumbnail file:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:269 +msgid "" +"%prog [options] file.lrs\n" +"Compile an LRS file into an LRF file." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 +msgid "Path to output file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:115 +msgid "Verbose processing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 +msgid "Convert LRS to LRS, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:455 +msgid "Invalid LRF file. Could not set metadata." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:580 +msgid "" +"%prog [options] mybook.lrf\n" +"\n" +"\n" +"Show/edit the metadata in an LRF file.\n" +"\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:43 +msgid "Set the book title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:589 +msgid "Set sort key for the title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:591 +msgid "Set the author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:593 +msgid "Set sort key for the author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:47 +msgid "The category this book belongs to. E.g.: History" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:598 +msgid "Path to a graphic that will be set as this files' thumbnail" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:601 +msgid "" +"Path to a txt file containing the comment to be stored in the lrf file." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:605 +msgid "Extract thumbnail from LRF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:606 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:182 +msgid "Set the publisher" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:607 +msgid "Set the book classification" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:608 +msgid "Set the book creator" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:609 +msgid "Set the book producer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:611 +msgid "" +"Extract cover from LRF file. Note that the LRF format has no defined cover, " +"so we use some heuristics to guess the cover." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:613 +msgid "Set book ID" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/mobi/convert_from.py:43 +msgid "" +"Usage: %prog [options] mybook.mobi|prc\n" +"\n" +"\n" +"%prog converts mybook.mobi to mybook.lrf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:47 +msgid "Could not find pdftohtml, check it is in your PATH" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:61 +msgid "" +" is an image based PDF. Only conversion of text based PDFs is supported." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:80 +msgid "" +"%prog [options] mybook.pdf\n" +"\n" +"\n" +"%prog converts mybook.pdf to mybook.lrf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:403 +msgid "" +"Path to output directory in which to create the HTML file. Defaults to " +"current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:405 +msgid "Be more verbose." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:417 +msgid "You must specify a single PDF file." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:21 +msgid "" +"%prog [options] mybook.rtf\n" +"\n" +"\n" +"%prog converts mybook.rtf to mybook.lrf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:146 +msgid "" +"This RTF file has a feature calibre does not support. Convert it to HTML and " +"then convert it." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:19 +msgid "" +"%prog [options] mybook.txt\n" +"\n" +"\n" +"%prog converts mybook.txt to mybook.lrf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:45 +msgid "Set the authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:49 +msgid "Set the comment" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:70 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:36 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:103 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:969 +msgid "Title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:970 +msgid "Author(s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:279 +msgid "Producer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:493 +msgid "Category" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:64 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:432 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:320 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:58 +msgid "Comments" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:109 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:309 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:909 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:973 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 +msgid "Tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:325 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 +msgid "Series" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:285 +msgid "Language" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:199 +msgid "A comma separated list of tags to set" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:201 +msgid "The series to which this book belongs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:203 +msgid "The series index" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:205 +msgid "The book language" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:207 +msgid "Extract the cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:54 +msgid "Usage:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:53 +msgid "Usage: imp-meta file.imp" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/imp.py:54 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:59 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:60 +msgid "No filename specified." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:97 +msgid "" +"\n" +"%prog [options] key\n" +"\n" +"Fetch metadata for books from isndb.com. You can specify either the \n" +"books ISBN ID or its title and author. If you specify the title and author,\n" +"then more than one book may be returned.\n" +"\n" +"key is the account key you generate after signing up for a free account from " +"isbndb.com.\n" +"\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:108 +msgid "The ISBN ID of the book you want metadata for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:110 +msgid "The author whose book to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:112 +msgid "The title of the book to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:114 +msgid "The publisher of the book to search for." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:47 +msgid "" +"Could not fetch cover as server is experiencing high load. Please try again " +"later." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:48 +msgid " not found." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:51 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:82 +msgid "LibraryThing.com server error. Try again later." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60 +msgid "" +"\n" +"%prog [options] ISBN\n" +"\n" +"Fetch a cover image for the book identified by ISBN from LibraryThing.com\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:35 +msgid "Usage: %s file.lit" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:45 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:227 +msgid "Cover saved to" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:178 +msgid "Set the subject tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:180 +msgid "Set the language" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:184 +msgid "Set the ISBN" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:965 +msgid "Set the dc:language field" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:58 +msgid "Usage: pdf-meta file.pdf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:59 +msgid "Usage: rb-meta file.rb" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/from_any.py:55 +msgid "Creating Mobipocket file from EPUB..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:499 +msgid "%prog [options] myebook.mobi" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:523 +msgid "Raw MOBI HTML saved in" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:512 +msgid "Options to control the conversion to MOBI" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:519 +msgid "Mobipocket-specific options." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:521 +msgid "" +"Compress file text using PalmDOC compression. Results in smaller files, but " +"takes a long time to run." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:524 +msgid "Modify images to meet Palm device size limitations." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:526 +msgid "Title for any generated in-line table of contents." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:527 +msgid "" +"Device renderer profiles. Affects conversion of font sizes, image rescaling " +"and rasterization of tables. Valid profiles are: %s." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:532 +msgid "Source renderer profile. Default is %default." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:535 +msgid "Destination renderer profile. Default is %default." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:543 +msgid "[options]" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:561 +msgid "Unknown source profile %r" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:565 +msgid "Unknown destination profile %r" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/odt/to_oeb.py:57 +msgid "The output directory. Defaults to the current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:586 +msgid "Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:587 +msgid "Title Page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:588 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/htmltoc.py:18 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:47 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:160 +msgid "Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:589 +msgid "Index" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:590 +msgid "Glossary" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:591 +msgid "Acknowledgements" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:592 +msgid "Bibliography" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:593 +msgid "Colophon" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:594 +msgid "Copyright" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:595 +msgid "Dedication" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:596 +msgid "Epigraph" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:597 +msgid "Foreword" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:598 +msgid "List of Illustrations" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:599 +msgid "List of Tables" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:600 +msgid "Notes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:601 +msgid "Preface" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:602 +msgid "Main Text" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:13 +msgid "Options to control the transformation of pdf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:24 +msgid "Number of pixels to crop from the left most x (default is %d) " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:26 +msgid "Number of pixels to crop from the left most y (default is %d) " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:28 +msgid "Number of pixels to crop from the right most x (default is %d) " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:30 +msgid "Number of pixels to crop from the right most y (default is %d)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:32 +msgid "" +"A file generated by ghostscript which allows each page to be individually " +"cropped [gs -dSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox > bounding] " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:38 +msgid "" +"\t%prog [options] file.pdf\n" +"\n" +"\tCrops a pdf. \n" +"\t" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:433 +msgid "Frequently used directories" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 +msgid "Send file to storage card instead of main memory by default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 +msgid "The format to use when saving single files to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 +msgid "Confirm before deleting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 +msgid "Toolbar icon size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 +msgid "Show button labels in the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 +msgid "Main window geometry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 +msgid "Notify when a new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 +msgid "Use Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 +msgid "Sort tags list by popularity" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 +msgid "Number of covers to show in the cover browsing mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:47 +msgid "Defaults for conversion to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:49 +msgid "Options for the LRF ebook viewer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:51 +msgid "Formats that are viewed using the internal viewer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:53 +msgid "Columns to be displayed in the book list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:54 +msgid "Automatically launch content server on application startup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:55 +msgid "Oldest news kept in database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:56 +msgid "Show system tray icon" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:58 +msgid "Upload downloaded news to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:60 +msgid "Delete books from library after uploading to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:62 +msgid "" +"Show the cover flow in a separate window instead of in the main calibre " +"window" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:64 +msgid "Disable notifications from the system tray icon" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:72 +msgid "Device no longer connected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:117 +msgid "Get device information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:128 +msgid "Get list of books on device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:137 +msgid "Send metadata to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:146 +msgid "Upload %d books to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:161 +msgid "Delete books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:176 +msgid "Download books from device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:186 +msgid "View book on device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:904 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 +msgid "Path" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:88 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 +msgid "Formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:61 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:88 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:52 +msgid "Dialog" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:62 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:50 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 +msgid "TextLabel" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:65 +msgid "&Previous" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:66 +msgid "&Next" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:40 +msgid "Choose Format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:34 +msgid "Set defaults for conversion of comics (CBR/CBZ files)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:49 +msgid "Set options for converting %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:89 +msgid "&Title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:90 +msgid "&Author(s):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91 +msgid "&Number of Colors:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:440 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 +msgid "&Profile:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:93 +msgid "Disable &normalize" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:94 +msgid "Keep &aspect ratio" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:95 +msgid "Disable &Sharpening" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 +msgid "&Landscape" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 +msgid "Don't so&rt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 +msgid "&Right to left" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:99 +msgid "De&speckle" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:100 +msgid "&Wide" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:100 +msgid " plugins" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:106 +msgid "by" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:123 +msgid "Advanced" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:123 +msgid "General" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:123 +msgid "Interface" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:124 +msgid "" +"Content\n" +"Server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:124 +msgid "Plugins" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:257 +msgid "No valid plugin path" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:258 +msgid "%s is not a valid plugin path" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:261 +msgid "Choose plugin" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:272 +msgid "Plugin cannot be disabled" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273 +msgid "The plugin: %s cannot be disabled" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:283 +msgid "Plugin not customizable" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:284 +msgid "Plugin: %s does not need customization" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287 +msgid "Customize %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:297 +msgid "Cannot remove builtin plugin" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:298 +msgid " cannot be removed. It is a builtin plugin. Try disabling it instead." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:319 +msgid "Error log:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:323 +msgid "Access log:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:385 +msgid "Failed to start content server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:385 +msgid "Invalid size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:385 +msgid "The size %s is invalid. must be of the form widthxheight" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:423 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:427 +msgid "Invalid database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:424 +msgid "<br>Must be a directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:424 +msgid "Invalid database location " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:428 +msgid "Invalid database location.<br>Cannot write to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:440 +msgid "Compacting database. This may take a while." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:440 +msgid "Compacting..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:417 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:343 +msgid "Configuration" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:418 +msgid "" +"&Location of ebooks (The ebooks are stored in folders sorted by author and " +"metadata is stored in the file metadata.db)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:419 +msgid "Browse for the new database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:437 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:452 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:453 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:414 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:497 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:308 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:327 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:344 +msgid "..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:421 +msgid "Show notification when &new version is available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:422 +msgid "" +"If you disable this setting, metadata is guessed from the filename instead. " +"This can be configured in the Advanced section." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:423 +msgid "Read &metadata from files" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:424 +msgid "Format for &single file save:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:425 +msgid "Default network &timeout:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:426 +msgid "" +"Set the default timeout for network fetches (i.e. anytime we go out to the " +"internet to get information)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:427 +msgid " seconds" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:428 +msgid "Choose &language (requires restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:429 +msgid "Normal" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:430 +msgid "High" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:431 +msgid "Low" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:432 +msgid "Job &priority:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:434 +msgid "Add a directory to the frequently used directories list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:436 +msgid "Remove a directory from the frequently used directories list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:438 +msgid "Use &Roman numerals for series number" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:439 +msgid "Enable system &tray icon (needs restart)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:440 +msgid "Show ¬ifications in system tray" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:441 +msgid "Show cover &browser in a separate window (needs restart)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:442 +msgid "Automatically send downloaded &news to ebook reader" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:443 +msgid "&Delete news from library when it is sent to reader" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:444 +msgid "&Number of covers to show in browse mode (needs restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:445 +msgid "Toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:446 +msgid "Large" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:447 +msgid "Medium" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:448 +msgid "Small" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:449 +msgid "&Button size in toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:450 +msgid "Show &text in toolbar buttons" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:451 +msgid "Select visible &columns in library view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:454 +msgid "Use internal &viewer for:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:455 +msgid "Free unused diskspace from the database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:456 +msgid "&Compact database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:457 +msgid "&Metadata from file name" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:458 +msgid "" +"calibre contains a network server that allows you to access your book " +"collection using a browser from anywhere in the world. Any changes to the " +"settings will only take effect after a server restart." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:459 +msgid "Server &port:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:460 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:174 +msgid "&Username:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:461 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:175 +msgid "&Password:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:462 +msgid "" +"If you leave the password blank, anyone will be able to access your book " +"collection using the web interface." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:463 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:176 +msgid "&Show password" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:464 +msgid "" +"The maximum size (widthxheight) for displayed covers. Larger covers are " +"resized. " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:465 +msgid "Max. &cover size:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:466 +msgid "&Start Server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:467 +msgid "St&op Server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:468 +msgid "&Test Server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:469 +msgid "Run server &automatically on startup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:470 +msgid "View &server logs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:471 +msgid "" +"If you want to use the content server to access your ebook collection on " +"your iphone with Stanza, you will need to add the URL " +"http://myhostname:8080/stanza as a new catalog in the stanza reader on your " +"iphone. Here myhostname should be the fully qualified hostname or the IP " +"address of this computer." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:472 +msgid "" +"Here you can customize the behavior of Calibre by controlling what plugins " +"it uses." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:473 +msgid "Enable/&Disable plugin" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:474 +msgid "&Customize plugin" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:475 +msgid "&Remove plugin" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:476 +msgid "Add new plugin" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:477 +msgid "Plugin &file:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:479 +msgid "&Add" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:48 +msgid "Are you sure?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:50 +msgid "&Show this warning again" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/conversion_error_ui.py:41 +msgid "ERROR" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:52 +msgid "Bulk convert to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:54 +msgid "Convert %s to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:68 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:143 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:161 +msgid "Metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:70 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:297 +msgid "Look & Feel" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:72 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:298 +msgid "Page Setup" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:98 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:61 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:299 +msgid "Chapter Detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:95 +msgid "" +"Specify metadata such as title and author for the book.\n" +"\n" +"Metadata will be updated in the database as well as the generated %s file." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +msgid "" +"Adjust the look of the generated ebook by specifying things like font sizes." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +msgid "Specify the page layout settings like margins." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:98 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:299 +msgid "Fine tune the detection of chapter and section headings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:167 +msgid "Choose cover for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:59 +msgid "Cannot read" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:60 +msgid "You do not have permission to read the file: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:68 +msgid "Error reading file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:69 +msgid "<p>There was an error reading from file: <br /><b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:127 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:190 +msgid " is not a valid picture" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1053 +msgid "Cannot convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:239 +msgid "This book has no available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 +msgid "No available formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:94 +msgid "Cannot convert %s as this book has no supported formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:249 +msgid "Choose the format to convert to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:260 +msgid "Invalid XPath expression" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:261 +msgid "The expression %s is invalid. Error: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:410 +msgid "Convert to EPUB" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:494 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:341 +msgid "Book Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:412 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:495 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:342 +msgid "Change &cover image:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:413 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:496 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:343 +msgid "Browse for an image to use as the cover of this book." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:415 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:498 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:416 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:499 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 +msgid "&Title: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:417 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:500 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 +msgid "Change the title of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:501 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 +msgid "&Author(s): " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:502 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 +msgid "" +"Change the author(s) of this book. Multiple authors should be separated by " +"an &. If the author name contains an &, use && to represent it." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 +msgid "Author So&rt:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 +msgid "" +"Change the author(s) of this book. Multiple authors should be separated by a " +"comma" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:422 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:318 +msgid "&Publisher: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:423 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:137 +msgid "Change the publisher of this book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:319 +msgid "Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:139 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:320 +msgid "" +"Tags categorize the book. This is particularly useful while searching. " +"<br><br>They can be any words or phrases, separated by commas." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:426 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:323 +msgid "&Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:427 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:428 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:145 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:146 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:324 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:325 +msgid "List of known series. You can add new series." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:429 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:430 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:328 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:329 +msgid "Series index." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:431 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:330 +msgid "Book " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:433 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +msgid "Source en&coding:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:434 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +msgid "Base &font size:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:442 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:444 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:448 +msgid " pt" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:436 +msgid "Remove &spacing between paragraphs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:437 +msgid "Preserve &tag structure when splitting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:438 +msgid "&Rescale images" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:439 +msgid "Override &CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:441 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:445 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:447 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:449 +msgid "Do not &split on page breaks" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:450 +msgid "&Source profile:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:451 +msgid "&Destination profile:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:452 +msgid "Automatic &chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:453 +msgid "&XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:454 +msgid "" +"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" " +"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +"<html><head><meta name=\"qrichtext\" content=\"1\" /><style " +"type=\"text/css\">\n" +"p, li { white-space: pre-wrap; }\n" +"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; " +"font-weight:400; font-style:normal;\">\n" +"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-" +"right:0px; -qt-block-indent:0; text-indent:0px;\">You can control how " +"calibre detects chapters using a XPath expression. To learn how to use XPath " +"expressions see the <a " +"href=\"https://calibre.kovidgoyal.net/user_manual/xpath.html\"><span " +"style=\" text-decoration: underline; color:#0000ff;\">XPath " +"tutorial</span></a></p></body></html>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:459 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:460 +msgid "Automatic &Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:461 +msgid "Number of &links to add to Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:462 +msgid "Do not add &detected chapters to the Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:463 +msgid "Chapter &threshold" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:464 +msgid "&Force use of auto-generated Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:465 +msgid "Level &1 TOC" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:466 +msgid "Level &2 TOC" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:467 +msgid "&Title for generated TOC" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:38 +msgid "Author Sort" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:40 +msgid "ISBN" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:104 +msgid "Cannot connect" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:105 +msgid "You must specify a valid access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:139 +msgid "Error fetching metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:144 +msgid "No metadata found" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:144 +msgid "" +"No metadata found, try adjusting the title and author or the ISBN key." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:77 +msgid "Fetch metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:78 +msgid "Fetching metadata for <b>%1</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:79 +msgid "" +"Sign up for a free account from <a " +"href=\"http://www.isbndb.com\">ISBNdb.com</a> to get an access key." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:80 +msgid "&Access Key:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:81 +msgid "Fetch" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:82 +msgid "Matches" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:83 +msgid "" +"Select the book that most closely matches your copy from the list below" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/job_view_ui.py:32 +msgid "Details of job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs.py:27 +msgid "Unavailable" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs.py:38 +msgid " - Jobs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:38 +msgid "Active Jobs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:39 +msgid "&Stop selected job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:98 +msgid "Choose the format to convert into LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:106 +msgid "Convert %s to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:109 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:360 +msgid "Set conversion defaults" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:260 +msgid "" +"Preprocess the file before converting to LRF. This is useful if you know " +"that the file is from a specific source. Known sources:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:261 +msgid "<ol><li><b>baen</b> - Books from BAEN Publishers</li>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:262 +msgid "" +"<li><b>pdftohtml</b> - HTML files that are the output of the program " +"pdftohtml</li>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:263 +msgid "<li><b>book-designer</b> - HTML0 files from Book Designer</li>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:296 +msgid "" +"Specify metadata such as title and author for the book.<p>Metadata will be " +"updated in the database as well as the generated LRF file." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:297 +msgid "" +"Adjust the look of the generated LRF file by specifying things like font " +"sizes and the spacing between words." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:298 +msgid "" +"Specify the page settings like margins and the screen size of the target " +"device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:308 +msgid "<font color=\"gray\">No help available</font>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:411 +msgid "Bulk convert ebooks to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:492 +msgid "Convert to LRF" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +msgid " pts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 +msgid "Embedded Fonts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 +msgid "&Serif:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 +msgid "S&ans-serif:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +msgid "&Monospace:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +msgid "Minimum &indent:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 +msgid "&Word spacing:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 +msgid "Enable auto &rotation of images" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 +msgid "Insert &blank lines between paragraphs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 +msgid "Ignore &tables" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 +msgid "Ignore &colors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 +msgid "&Preprocess:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 +msgid "Header" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 +msgid "&Show header" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 +msgid "&Header format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:535 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:540 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:544 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:546 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:109 +msgid " px" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +msgid "Header &separation:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 +msgid "Override<br>CSS" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 +msgid "&Convert tables to images (good for large/complex tables)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 +msgid "&Multiplier for text size in rendered tables:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +msgid "Title based detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:550 +msgid "&Disable chapter detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +msgid "&Regular expression:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +msgid "Add &chapters to table of contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +msgid "Don't add &links to the table of contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:554 +msgid "Tag based detection" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +msgid "&Page break before tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:556 +msgid "&Force page break before tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 +msgid "Force page break before &attribute:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 +msgid "Detect chapter &at tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 +msgid "" +"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" " +"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +"<html><head><meta name=\"qrichtext\" content=\"1\" /><style " +"type=\"text/css\">\n" +"p, li { white-space: pre-wrap; }\n" +"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; " +"font-weight:400; font-style:normal;\">\n" +"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; " +"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-" +"indent:0px;\"></p></body></html>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:126 +msgid "Edit Meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:127 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:304 +msgid "Meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:310 +msgid "Author S&ort: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +msgid "" +"Specify how the author(s) of this book should be sorted. For example Charles " +"Dickens should be sorted as Dickens, Charles." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 +msgid "&Rating:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 +msgid "Rating of this book. 0-5 stars" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 +msgid " stars" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:138 +msgid "Add Ta&gs: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:140 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:141 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:321 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:322 +msgid "Open Tag Editor" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:142 +msgid "&Remove tags:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:143 +msgid "Comma separated list of tags to remove from the books. " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:147 +msgid "Remove &format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:148 +msgid "A&utomatically set author sort" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:124 +msgid "Could not read metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:125 +msgid "Could not read metadata from %s format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:139 +msgid "Could not read cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:134 +msgid "Could not read cover from %s format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:140 +msgid "The cover in the %s format is invalid" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:319 +msgid "" +"<p>Enter your username and password for <b>LibraryThing.com</b>. <br/>If you " +"do not have one, you can <a href='http://www.librarything.com'>register</a> " +"for free!.</p>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:349 +msgid "<b>Could not fetch cover.</b><br/>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:349 +msgid "Could not fetch cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:355 +msgid "Cannot fetch cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:355 +msgid "You must specify the ISBN identifier for this book." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +msgid "Edit Meta Information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 +msgid "Swap the author and title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:312 +msgid "" +"Automatically create the author sort entry based on the current author entry" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:326 +msgid "Remove unused series (Series that have no books)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:331 +msgid "IS&BN:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:333 +msgid "Fetch metadata from server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:334 +msgid "Available Formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:335 +msgid "Add a new format for this book to the database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:337 +msgid "Remove the selected formats for this book from the database." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:339 +msgid "Set the cover for the book from the selected format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:345 +msgid "Reset cover to default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:347 +msgid "Fetch cover image from server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:348 +msgid "" +"Change the username and/or password for your account at LibraryThing.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:349 +msgid "Change password" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:55 +msgid "Password needed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress.py:42 +msgid "Aborting..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:39 +msgid "You" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:218 +msgid "Search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:261 +msgid "%d recipes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +msgid "Monday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +msgid "Tuesday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +msgid "Wednesday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +msgid "day" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +msgid "Friday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +msgid "Saturday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +msgid "Sunday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +msgid "Thursday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:292 +msgid "Must set account information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:292 +msgid "This recipe requires a username and password" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:317 +msgid "Created by: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:355 +msgid "Last downloaded: %s days ago" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:357 +msgid "Last downloaded: never" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:384 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:161 +msgid "Schedule news download" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:387 +msgid "Add a custom news source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:394 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:772 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:776 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1083 +msgid "News" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221 +msgid "Recipes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:163 +msgid "Schedule for download" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:164 +msgid "title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:165 +msgid "description" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:166 +msgid "author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:167 +msgid "&Schedule for download:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:170 +msgid "Every " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:169 +msgid "at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:171 +msgid "" +"Interval at which to download this recipe. A value of zero means that the " +"recipe will be downloaded every hour." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:180 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:263 +msgid " days" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:173 +msgid "&Account" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:177 +msgid "For the scheduling to work, you must leave calibre running." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:178 +msgid "&Download now" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:179 +msgid "" +"Delete downloaded news older than the specified number of days. Set to zero " +"to disable." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:181 +msgid "Delete downloaded news older than " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:35 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:96 +msgid "Form" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:36 +msgid "contains" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:37 +msgid "The text to search for. It is interpreted as a regular expression." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:38 +msgid "" +"<p>Negate this match. That is, only return results that <b>do not</b> match " +"this query." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:39 +msgid "Negate" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:87 +msgid "Advanced Search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:88 +msgid "Find entries that have..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:89 +msgid "&All these words:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:90 +msgid "This exact &phrase:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:91 +msgid "&One or more of these words:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:92 +msgid "But dont show entries that have..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:93 +msgid "Any of these &unwanted words:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:94 +msgid "" +"See the <a href=\"http://calibre.kovidgoyal.net/user_manual/gui.html#the-" +"search-interface\">User Manual</a> for more help" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:123 +msgid "Tag Editor" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:124 +msgid "A&vailable tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:125 +msgid "" +"Delete tag from database. This will unapply the tag from all books and then " +"remove it from the database." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:127 +msgid "Apply tag to current book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:129 +msgid "A&pplied tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:130 +msgid "Unapply (remove) tag from current book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:132 +msgid "&Add tag:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:133 +msgid "" +"If the tag you want is not in the available list, you can add it here. " +"Accepts a comma separated list of tags." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:134 +msgid "Add tag to available tags and apply it to current book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:62 +msgid "No recipe selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:68 +msgid "The attached file: %s is a recipe to download %s." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:69 +msgid "Recipe for " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:255 +msgid "Switch to Advanced mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:99 +msgid "Switch to Basic mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:109 +msgid "Feed must have a title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:110 +msgid "The feed must have a title" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:114 +msgid "Feed must have a URL" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:115 +msgid "The feed %s must have a URL" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:120 +msgid "Already exists" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:121 +msgid "This feed has already been added to the recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228 +msgid "Invalid input" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229 +msgid "<p>Could not create recipe. Error:<br>%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234 +msgid "Replace recipe?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235 +msgid "A custom recipe named %s already exists. Do you want to replace it?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:201 +msgid "Pick recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:201 +msgid "Pick the recipe to customize" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221 +msgid "Choose a recipe file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:248 +msgid "Add custom news source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:249 +msgid "Available user recipes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:250 +msgid "Add/Update &recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:251 +msgid "&Remove recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:252 +msgid "&Share recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:253 +msgid "Customize &builtin recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:254 +msgid "&Load recipe from file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:256 +msgid "" +"<html><head><meta name=\"qrichtext\" content=\"1\" /><style " +"type=\"text/css\">\n" +"p, li { white-space: pre-wrap; }\n" +"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; " +"font-weight:400; font-style:normal;\">\n" +"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-" +"right:0px; -qt-block-indent:0; text-indent:0px;\">Create a basic news " +"recipe, by adding RSS feeds to it. <br />For most feeds, you will have to " +"use the \"Advanced mode\" to further customize the fetch " +"process.</p></body></html>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:260 +msgid "Recipe &title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:261 +msgid "&Oldest article:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:262 +msgid "The oldest article to download" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:264 +msgid "&Max. number of articles per feed:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:265 +msgid "Maximum number of articles to download per feed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:266 +msgid "Feeds in recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:268 +msgid "Remove feed from recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:274 +msgid "Add feed to recipe" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:272 +msgid "&Feed title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:273 +msgid "Feed &URL:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:275 +msgid "&Add feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:276 +msgid "" +"For help with writing advanced news recipes, please visit <a " +"href=\"http://calibre.kovidgoyal.net/user_manual/news.html\">User Recipes</a>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:277 +msgid "Recipe source code (python)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:97 +msgid "" +"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" " +"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +"<html><head><meta name=\"qrichtext\" content=\"1\" /><style " +"type=\"text/css\">\n" +"p, li { white-space: pre-wrap; }\n" +"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; " +"font-weight:400; font-style:normal;\">\n" +"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-" +"right:0px; -qt-block-indent:0; text-indent:0px;\">Set a regular expression " +"pattern to use when trying to guess ebook metadata from filenames. </p>\n" +"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-" +"right:0px; -qt-block-indent:0; text-indent:0px;\">A <a " +"href=\"http://docs.python.org/lib/re-syntax.html\"><span style=\" text-" +"decoration: underline; color:#0000ff;\">reference</span></a> on the syntax " +"of regular expressions is available.</p>\n" +"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-" +"right:0px; -qt-block-indent:0; text-indent:0px;\">Use the <span style=\" " +"font-weight:600;\">Test</span> functionality below to test your regular " +"expression on a few sample filenames. The group names for the various " +"metadata entries are documented in tooltips.</p></body></html>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:104 +msgid "Regular &expression" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:105 +msgid "&Test" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:106 +msgid "File &name:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:107 +msgid "Test" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:108 +msgid "Title:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:109 +msgid "Regular expression (?P<title>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:113 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70 +msgid "No match" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:111 +msgid "Authors:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:112 +msgid "Regular expression (?P<authors>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:114 +msgid "Series:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:115 +msgid "Regular expression (?P<series>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:117 +msgid "Series index:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:118 +msgid "Regular expression (?P<series_index>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:120 +msgid "ISBN:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:121 +msgid "Regular expression (?P<isbn>)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46 +msgid "Job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47 +msgid "Status" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48 +msgid "Progress" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49 +msgid "Running time" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65 +msgid "Unknown job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70 +msgid "Finished" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:72 +msgid "Error" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:74 +msgid "Waiting" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:76 +msgid "Working" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:176 +msgid "Cannot kill job" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:173 +msgid "Cannot kill jobs that communicate with the device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:177 +msgid "Job has already run" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:971 +msgid "Size (MB)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:972 +msgid "Date" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:107 +msgid "Rating" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:308 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:319 +msgid "None" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:325 +msgid "Book <font face=\"serif\">%s</font> of %s." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:739 +msgid "Not allowed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:740 +msgid "" +"Dropping onto a device is not supported. First add the book to the calibre " +"library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:903 +msgid "Format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:908 +msgid "Timestamp" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:1006 +msgid "Search (For Advanced Search click the button to the left)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/config_ui.py:47 +msgid "Configure Viewer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/config_ui.py:48 +msgid "Use white background" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/config_ui.py:49 +msgid "Hyphenate" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/config_ui.py:50 +msgid "<b>Changes will only take effect after a restart.</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:64 +msgid " - LRF Viewer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 +msgid "<b>No matches</b> for the search phrase <i>%s</i> were found." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:378 +msgid "No matches found" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:128 +msgid "LRF Viewer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:129 +msgid "Parsing LRF file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:130 +msgid "LRF Viewer toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:131 +msgid "Next Page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:132 +msgid "Previous Page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:154 +msgid "Back" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:155 +msgid "Forward" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:135 +msgid "Next match" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:162 +msgid "Open ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:137 +msgid "Configure" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:90 +msgid "Error communicating with device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:102 +msgid "&Restore" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:103 +msgid "&Donate to support calibre" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:106 +msgid "&Restart" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:142 +msgid "" +"<p>For help visit <a " +"href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:143 +msgid "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:163 +msgid "Send to main memory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:164 +msgid "Send to storage card" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:164 +msgid "and delete from library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:166 +msgid "Send to storage card by default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 +msgid "Edit metadata individually" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +msgid "Edit metadata in bulk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:184 +msgid "Add books from a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:185 +msgid "" +"Add books from directories, including sub-directories (One book per " +"directory, assumes every ebook file is the same book in a different format)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:186 +msgid "" +"Add books from directories, including sub directories (Multiple books per " +"directory, assumes every ebook file is a different book)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:201 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:356 +msgid "Save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:202 +msgid "Save to disk in a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:203 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1258 +msgid "Save only %s format to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:206 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:362 +msgid "View" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:207 +msgid "View specific format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:224 +msgid "Convert individually" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:225 +msgid "Bulk convert" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:227 +msgid "Set defaults for conversion" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:228 +msgid "Set defaults for conversion of comics" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:250 +msgid "Similar books..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:298 +msgid "Bad database location" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1391 +msgid "Choose a location for your ebook library." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:424 +msgid "Browse by covers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:513 +msgid "Device: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:514 +msgid " detected." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 +msgid "Connected " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:547 +msgid "Device database corrupted" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:548 +msgid "" +"\n" +" <p>The database of books on the reader is corrupted. Try the " +"following:\n" +" <ol>\n" +" <li>Unplug the reader. Wait for it to finish regenerating " +"the database (i.e. wait till it is ready to be used). Plug it back in. Now " +"it should work with %(app)s. If not try the next step.</li>\n" +" <li>Quit %(app)s. Find the file media.xml in the reader's " +"main memory. Delete it. Unplug the reader. Wait for it to regenerate the " +"file. Re-connect it and start %(app)s.</li>\n" +" </ol>\n" +" " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:597 +msgid "Adding books recursively..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:602 +msgid "Added " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:602 +msgid "Searching..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:612 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:716 +msgid "" +"<p>Books with the same title as the following already exist in the database. " +"Add them anyway?<ul>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:719 +msgid "Duplicates found!" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:649 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:673 +msgid "Uploading books to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:657 +msgid "Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:658 +msgid "EPUB Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:659 +msgid "LRF Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:660 +msgid "HTML Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:661 +msgid "LIT Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:662 +msgid "MOBI Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:663 +msgid "Text books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +msgid "PDF Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:665 +msgid "Comics" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:666 +msgid "Archives" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +msgid "Adding books..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +msgid "Reading metadata..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:707 +msgid "Read metadata from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:710 +msgid "Adding books to database..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:751 +msgid "No space on device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +msgid "" +"<p>Cannot upload books to device there is no more free space available " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:784 +msgid "" +"The selected books will be <b>permanently deleted</b> and the files removed " +"from your computer. Are you sure?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:793 +msgid "Deleting books from device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:824 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:849 +msgid "Cannot edit metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:824 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:849 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:974 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1053 +msgid "No books selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:900 +msgid "Sending news to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 +msgid "Sending books to device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:956 +msgid "No suitable formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:957 +msgid "" +"Could not upload the following books to the device, as no suitable formats " +"were found:<br><ul>%s</ul>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:974 +msgid "Cannot save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:978 +msgid "Saving to disk..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:983 +msgid "Saved" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:989 +msgid "Choose destination directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1003 +msgid "" +"<p>Could not save the following books to disk, because the %s format is not " +"available for them:<ul>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 +msgid "Could not save some ebooks" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1029 +msgid "Fetching news from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1043 +msgid " fetched." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1164 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1182 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1194 +msgid "No book selected" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1164 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1194 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1210 +msgid "Cannot view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1170 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1215 +msgid "Choose the format to view" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1182 +msgid "Cannot open folder" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 +msgid "%s has no available formats." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1249 +msgid "Cannot configure" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1249 +msgid "Cannot configure while there are running jobs." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1267 +msgid "Copying database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1269 +msgid "Copying library to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1279 +msgid "Invalid database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1280 +msgid "" +"<p>An invalid database already exists at %s, delete it before trying to move " +"the existing database.<br>Error: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1286 +msgid "Could not move database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1306 +msgid "No detailed info available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1307 +msgid "No detailed information is available for books on the device." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1350 +msgid "Error talking to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1351 +msgid "" +"There was a temporary error talking to the device. Please unplug and " +"reconnect the device and or reboot." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1364 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1379 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1383 +msgid "Conversion Error" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1365 +msgid "" +"<p>Could not convert: %s<p>It is a <a href=\"%s\">DRM</a>ed book. You must " +"first remove the DRM using 3rd party tools." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1435 +msgid "" +"is the result of the efforts of many volunteers from all over the world. If " +"you find it useful, please consider donating to support its development." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1457 +msgid "There are active jobs. Are you sure you want to quit?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1459 +msgid "" +" is communicating with the device!<br>\n" +" 'Quitting may cause corruption on the device.<br>\n" +" 'Are you sure you want to quit?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1463 +msgid "WARNING: Active jobs" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1497 +msgid "" +"will keep running in the system tray. To close it, choose <b>Quit</b> in the " +"context menu of the system tray." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1514 +msgid "" +"<span style=\"color:red; font-weight:bold\">Latest version: <a " +"href=\"%s\">%s</a></span>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1519 +msgid "" +"%s has been updated to version %s. See the <a " +"href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. " +"Visit the download page?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1519 +msgid "Update available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1534 +msgid "Use the library located at the specified path." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1536 +msgid "Start minimized to system tray." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1538 +msgid "Log debugging information to console" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:328 +msgid "calibre" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:330 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:331 +msgid "Donate to support the development of calibre" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:333 +msgid "Output:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:334 +msgid "" +"Set the output format that is used when converting ebooks and downloading " +"news" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:335 +msgid "Advanced search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:337 +msgid "Alt+S" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:338 +msgid "&Search:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:339 +msgid "" +"Search the list of books by title or author<br><br>Words separated by spaces " +"are ANDed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:340 +msgid "" +"Search the list of books by title, author, publisher, tags and " +"comments<br><br>Words separated by spaces are ANDed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:341 +msgid "Reset Quick Search" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:345 +msgid "Match any" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:346 +msgid "Match all" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:347 +msgid "Sort by &popularity" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:348 +msgid "Add books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:349 +msgid "A" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:351 +msgid "Remove books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:352 +msgid "Del" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:353 +msgid "Edit meta information" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:354 +msgid "E" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:355 +msgid "Send to device" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:357 +msgid "S" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:358 +msgid "Fetch news" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:359 +msgid "F" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:360 +msgid "Convert E-books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:361 +msgid "C" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:363 +msgid "V" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:364 +msgid "Open containing folder" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:365 +msgid "Show book details" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:366 +msgid "Books by same author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:367 +msgid "Books in this series" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:368 +msgid "Books by this publisher" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:369 +msgid "Books with the same tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:18 +msgid "" +"Redirect console output to a dialog window (both stdout and stderr). Useful " +"on windows where GUI apps do not have a output streams." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:53 +msgid "&Preferences" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:54 +msgid "&Quit" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:80 +msgid "ERROR: Unhandled exception" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:115 +msgid "Jobs:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:124 +msgid "Click to see list of active jobs." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:154 +msgid "Click to browse books by their covers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:154 +msgid "Click to turn off Cover Browsing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 +msgid "" +"<p>Browsing books by their covers is disabled.<br>Import of pictureflow " +"module failed:<br>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:167 +msgid "Click to browse books by tags" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 +msgid "Authors" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 +msgid "Publishers" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:117 +msgid "Convert book: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:151 +msgid "Convert comic: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:267 +msgid "Starting Bulk conversion of %d books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:335 +msgid "Convert book %d of %d (%s)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:344 +msgid "" +"<p>Could not convert %d of %d books, because no suitable source format was " +"found.<ul>%s</ul>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:248 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:345 +msgid "Could not convert some books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:372 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:387 +msgid "Fetch news from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:384 +msgid "You must set a username and password for %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:101 +msgid "Configure Ebook viewer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:102 +msgid "&Font options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:103 +msgid "Se&rif family:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:104 +msgid "&Sans family:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:105 +msgid "&Monospace family:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:106 +msgid "&Default font size:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:108 +msgid "Monospace &font size:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:110 +msgid "S&tandard font:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:111 +msgid "Serif" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:112 +msgid "Sans-serif" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:113 +msgid "Monospace" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:114 +msgid "&User stylesheet" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:49 +msgid "Options to customize the ebook viewer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:82 +msgid "" +"Set the user CSS stylesheet. This can be used to customize the look of all " +"books." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:58 +msgid "Font options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:59 +msgid "The serif font family" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:60 +msgid "The sans-serif font family" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:61 +msgid "The monospaced font family" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:62 +msgid "The standard font size in px" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:63 +msgid "The monospaced font size in px" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:64 +msgid "The standard font type" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:166 +msgid "Go to..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:207 +msgid "Position in book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:208 +msgid "/Unknown" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:213 +msgid "Go to a reference. To get reference numbers, use the reference mode." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:219 +msgid "Search for text in book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:339 +msgid "Choose ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:340 +msgid "Ebooks" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:358 +msgid "Add bookmark" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:358 +msgid "Enter title for bookmark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:379 +msgid "No matches found for: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:419 +msgid "Loading flow..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:446 +msgid "Laying out %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:498 +msgid "Loading ebook..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:506 +msgid "<p>This book is protected by <a href=\"%s\">DRM</a>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:506 +msgid "DRM Error" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:508 +msgid "Could not open ebook" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:509 +msgid "<b>%s</b><br/><p>%s</p>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:569 +msgid "Options to control the ebook viewer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:578 +msgid "" +"%prog [options] file\n" +"\n" +"View an ebook. \n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:152 +msgid "Ebook Viewer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:153 +msgid "toolBar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:156 +msgid "Next page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:157 +msgid "Previous page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:158 +msgid "Font size larger" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:159 +msgid "Font size smaller" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:163 +msgid "Find next" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:164 +msgid "Copy to clipboard" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:165 +msgid "Preferences" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:166 +msgid "Reference Mode" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:167 +msgid "Bookmark" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:168 +msgid "Toggle full screen" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47 +msgid "Invalid regular expression" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48 +msgid "Invalid regular expression: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:139 +msgid "" +"Library\n" +"%d\n" +"books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:140 +msgid "" +"Reader\n" +"%s\n" +"available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:141 +msgid "" +"Card\n" +"%s\n" +"available" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:146 +msgid "Click to see the list of books available on your computer" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:147 +msgid "Click to see the list of books in the main memory of your reader" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:148 +msgid "Click to see the list of books on the storage card in your reader" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/__init__.py:16 +msgid "Settings to control the calibre content server" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/__init__.py:20 +msgid "The port on which to listen. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/__init__.py:22 +msgid "The server timeout in seconds. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/__init__.py:24 +msgid "The max number of worker threads to use. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/__init__.py:26 +msgid "Set a password to restrict access. By default access is unrestricted." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/__init__.py:28 +msgid "Username for access. By default, it is: %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/__init__.py:32 +msgid "The maximum size for displayed covers. Default is %default." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:107 +msgid "" +"Path to the calibre library. Default is to use the path stored in the " +"settings." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:184 +msgid "" +"%prog list [options]\n" +"\n" +"List the books available in the calibre database.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:192 +msgid "" +"The fields to display when listing books in the database. Should be a comma " +"separated list of fields.\n" +"Available fields: %s\n" +"Default: %%default. The special field \"all\" can be used to select all " +"fields. Only has effect in the text output format." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:194 +msgid "" +"The field by which to sort the results.\n" +"Available fields: %s\n" +"Default: %%default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:196 +msgid "Sort results in ascending order" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:198 +msgid "" +"Filter the results by the search query. For the format of the search query, " +"please see the search related documentation in the User Manual. Default is " +"to do no filtering." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:200 +msgid "" +"The maximum width of a single line in the output. Defaults to detecting " +"screen size." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:201 +msgid "The string used to separate fields. Default is a space." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:202 +msgid "" +"The prefix for all file paths. Default is the absolute path to the library " +"folder." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:205 +msgid "" +"The format in which to output the data. Available choices: %s. Defaults is " +"text." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:213 +msgid "Invalid fields. Available fields:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:220 +msgid "Invalid sort field. Available fields:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:286 +msgid "" +"The following books were not added as they already exist in the database " +"(see --duplicates option):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:310 +msgid "" +"%prog add [options] file1 file2 file3 ...\n" +"\n" +"Add the specified files as books to the database. You can also specify " +"directories, see\n" +"the directory related options below.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:319 +msgid "" +"Assume that each directory has only a single logical book and that all files " +"in it are different e-book formats of that book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 +msgid "Process directories recursively" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:323 +msgid "" +"Add books to database even if they already exist. Comparison is done based " +"on book titles." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:328 +msgid "You must specify at least one file to add" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:346 +msgid "" +"%prog remove ids\n" +"\n" +"Remove the books identified by ids from the database. ids should be a comma " +"separated list of id numbers (you can get id numbers by using the list " +"command). For example, 23,34,57-85\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:358 +msgid "You must specify at least one book to remove" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:378 +msgid "" +"%prog add_format [options] id ebook_file\n" +"\n" +"Add the ebook in ebook_file to the available formats for the logical book " +"identified by id. You can get id by using the list command. If the format " +"already exists, it is replaced.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:389 +msgid "You must specify an id and an ebook file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:394 +msgid "ebook file must have an extension" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 +msgid "" +"\n" +"%prog remove_format [options] id fmt\n" +"\n" +"Remove the format fmt from the logical book identified by id. You can get id " +"by using the list command. fmt should be a file extension like LRF or TXT or " +"EPUB. If the logical book does not have fmt available, do nothing.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:415 +msgid "You must specify an id and a format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:433 +msgid "" +"\n" +"%prog show_metadata [options] id\n" +"\n" +"Show the metadata stored in the calibre database for the book identified by " +"id.\n" +"id is an id number from the list command.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:441 +msgid "Print metadata in OPF form (XML)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:446 +msgid "You must specify an id" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:460 +msgid "" +"\n" +"%prog set_metadata [options] id /path/to/metadata.opf\n" +"\n" +"Set the metadata stored in the calibre database for the book identified by " +"id\n" +"from the OPF file metadata.opf. id is an id number from the list command. " +"You\n" +"can get a quick feel for the OPF format by using the --as-opf switch to the\n" +"show_metadata command.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:473 +msgid "You must specify an id and a metadata file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:485 +msgid "" +"%prog export [options] ids\n" +"\n" +"Export the books specified by ids (a comma separated list) to the " +"filesystem.\n" +"The export operation saves all formats of the book, its cover and metadata " +"(in\n" +"an opf file). You can get id numbers from the list command.\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:493 +msgid "Export all books in database, ignoring the list of ids." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:495 +msgid "Export books to the specified directory. Default is" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:497 +msgid "Export all books into a single directory" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:499 +msgid "Create file names as author - title instead of title - author" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:504 +msgid "You must specify some ids or the %s option" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/cli.py:514 +msgid "" +"%%prog command [options] [arguments]\n" +"\n" +"%%prog is the command line interface to the calibre books database.\n" +"\n" +"command is one of:\n" +" %s\n" +"\n" +"For help on an individual command: %%prog command --help\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1179 +msgid "<p>Copying books to %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1192 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1301 +msgid "Copying <b>%s</b>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1272 +msgid "<p>Migrating old database to ebook library in %s<br><center>" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1318 +msgid "Compacting database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/server.py:139 +msgid "Password to access your calibre library. Username is " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/library/server.py:384 +msgid "" +"[options]\n" +"\n" +"Start the calibre content server." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:387 +msgid "Could not launch worker process." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/parallel.py:813 +msgid "Job stopped by user" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:43 +msgid "%sUsage%s: %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:81 +msgid "Created by " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:529 +msgid "Path to the database in which books are stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:531 +msgid "Pattern to guess metadata from filenames" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:533 +msgid "Access key for isbndb.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:535 +msgid "Default timeout for network operations (seconds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:537 +msgid "Path to directory in which your library of books is stored" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:539 +msgid "The language in which to display the user interface" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:541 +msgid "The default output format for ebook conversions." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:543 +msgid "Read metadata from files" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:545 +msgid "The priority of worker processes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:180 +msgid "Could not initialize the fontconfig library" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/sftp.py:53 +msgid "URL must have the scheme sftp" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/sftp.py:57 +msgid "host must be of the form user@hostname" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/sftp.py:68 +msgid "Failed to negotiate SSH session: " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/sftp.py:71 +msgid "Failed to authenticate with server: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:76 +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:97 +msgid "Unknown feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:115 +#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:137 +msgid "Untitled article" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:15 +msgid "Options to control the fetching of periodical content from the web." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:18 +msgid "Customize the download engine" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:20 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:455 +msgid "" +"Timeout in seconds to wait for a response from the server. Default: %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:22 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:463 +msgid "" +"Minimum interval in seconds between consecutive fetches. Default is %default " +"s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:24 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:465 +msgid "" +"The character encoding for the websites you are trying to download. The " +"default is to try and guess the encoding." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:26 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:467 +msgid "" +"Only links that match this regular expression will be followed. This option " +"can be specified multiple times, in which case as long as a link matches any " +"one regexp, it will be followed. By default all links are followed." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:28 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:469 +msgid "" +"Any link that matches this regular expression will be ignored. This option " +"can be specified multiple times, in which case as long as any regexp matches " +"a link, it will be ignored.By default, no links are ignored. If both --" +"filter-regexp and --match-regexp are specified, then --filter-regexp is " +"applied first." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:30 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:471 +msgid "Do not download CSS stylesheets." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:33 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:90 +msgid "" +"Specify a list of feeds to download. For example: \n" +"\"['http://feeds.newsweek.com/newsweek/TopNews', " +"'http://feeds.newsweek.com/headlines/politics']\"\n" +"If you specify this option, any argument to %prog is ignored and a default " +"recipe is used to download the feeds." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:94 +msgid "Be more verbose while processing." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:39 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +msgid "" +"The title for this recipe. Used as the title for any ebooks created from the " +"downloaded feeds." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:41 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 +msgid "Username for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:43 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:98 +msgid "Password for sites that require a login to access content." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:101 +msgid "" +"Number of levels of links to follow on webpages that are linked to from " +"feeds. Defaul %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:53 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:103 +msgid "" +"The directory in which to store the downloaded feeds. Defaults to the " +"current directory." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:55 +msgid "Don't show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:107 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:109 +msgid "" +"Useful for recipe development. Forces max_articles_per_feed to 2 and " +"downloads at most 2 feeds." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:63 +msgid "" +"%%prog [options] ARG\n" +"\n" +"%%prog parses an online source of articles, like an RSS or ATOM feed and \n" +"fetches the article contents organized in a nice hierarchy.\n" +"\n" +"ARG can be one of:\n" +"\n" +"file name - %%prog will try to load a recipe from the file\n" +"\n" +"builtin recipe title - %%prog will load the builtin recipe and use it to " +"fetch the feed. For e.g. Newsweek or \"The BBC\" or \"The New York Times\"\n" +"\n" +"recipe as a string - %%prog will load the recipe directly from the string " +"arg.\n" +"\n" +"Available builtin recipes are:\n" +"%s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:87 +msgid "" +"Options to control web2disk (used to fetch websites linked from feeds)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:105 +msgid "Dont show the progress bar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:120 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:681 +msgid "Fetching feeds..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:41 +msgid "Unknown News Source" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:560 +msgid "Download finished" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 +msgid "Failed to download the following articles:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:564 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:570 +msgid " from " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:568 +msgid "Failed to download parts of the following articles:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:572 +msgid "\tFailed links:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:660 +msgid "Could not fetch article. Run with --debug to see the reason" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:685 +msgid "Got feeds from index page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:691 +msgid "Trying to download cover..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:744 +msgid "Starting download [%d thread(s)]..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 +msgid "Feeds downloaded to %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:770 +msgid "Could not download cover: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:777 +msgid "Downloading cover from %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:910 +msgid "Untitled Article" +msgstr "مقال بلا عنوان" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:965 +msgid "" +"\n" +"Downloaded article %s from %s\n" +"%s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:971 +msgid "Article downloaded: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:977 +msgid "Failed to download article: %s from %s\n" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:982 +msgid "Article download failed: %s" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:997 +msgid "Fetching feed" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:449 +msgid "" +"%prog URL\n" +"\n" +"Where URL is for example http://google.com" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:452 +msgid "Base directory into which URL is saved. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:458 +msgid "" +"Maximum number of levels to recurse i.e. depth of links to follow. Default " +"%default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:461 +msgid "" +"The maximum number of files to download. This only applies to files from <a " +"href> tags. Default is %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:472 +msgid "Show detailed output information. Useful for debugging" +msgstr "" diff --git a/src/calibre/translations/bg.po b/src/calibre/translations/bg.po index 4a8f3c767a..c14acfa0b5 100644 --- a/src/calibre/translations/bg.po +++ b/src/calibre/translations/bg.po @@ -13,7 +13,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" diff --git a/src/calibre/translations/ca.po b/src/calibre/translations/ca.po index fbb81a4cd9..eea31fb92f 100644 --- a/src/calibre/translations/ca.po +++ b/src/calibre/translations/ca.po @@ -17,7 +17,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/cs.po b/src/calibre/translations/cs.po index 2b7eff374a..b9a95c1310 100644 --- a/src/calibre/translations/cs.po +++ b/src/calibre/translations/cs.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/de.po b/src/calibre/translations/de.po index 2ca5e4993d..498524dde7 100644 --- a/src/calibre/translations/de.po +++ b/src/calibre/translations/de.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" diff --git a/src/calibre/translations/el.po b/src/calibre/translations/el.po index 1d29b6c5f9..708ff7182a 100644 --- a/src/calibre/translations/el.po +++ b/src/calibre/translations/el.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/es.po b/src/calibre/translations/es.po index 90a037cf75..7973cf7ba9 100644 --- a/src/calibre/translations/es.po +++ b/src/calibre/translations/es.po @@ -17,7 +17,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/fr.po b/src/calibre/translations/fr.po index 81c0bc21ec..6474c3567e 100644 --- a/src/calibre/translations/fr.po +++ b/src/calibre/translations/fr.po @@ -13,7 +13,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" diff --git a/src/calibre/translations/gl.po b/src/calibre/translations/gl.po index e2de5d5aae..330ad58f0e 100644 --- a/src/calibre/translations/gl.po +++ b/src/calibre/translations/gl.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/hu.po b/src/calibre/translations/hu.po index 9f574726f9..c58e154bc0 100644 --- a/src/calibre/translations/hu.po +++ b/src/calibre/translations/hu.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2009-01-27 01:54+0000\n" -"PO-Revision-Date: 2009-01-23 21:22+0000\n" -"Last-Translator: Molnár Gábor <csirkus@gmail.com>\n" +"PO-Revision-Date: 2009-02-04 20:39+0000\n" +"Last-Translator: Kovid Goyal <Unknown>\n" "Language-Team: Hungarian <hu@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 @@ -142,7 +142,7 @@ msgstr "Tömörített könyvek metaadatait is olvassa be" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:196 msgid "Read metadata from ebooks in RAR archives" -msgstr "" +msgstr "Metaadatok olvasása a RAR-ral tömörített könyvekből is" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:207 #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:217 @@ -274,7 +274,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 msgid "Control auto-detection of document structure." -msgstr "" +msgstr "Dokumentum-struktúra automatikus felismerése." #: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 msgid "" @@ -832,6 +832,9 @@ msgid "" "FONT_DELTA pts. FONT_DELTA can be a fraction.If FONT_DELTA is negative, the " "font size is decreased." msgstr "" +"A betűméret nővelése 2*FONT_DELTA ponttal, és a sortávolság növelése " +"FONT_DELTA ponttal. A FONT_DELTA érték törtszám is lehet, valamint ha " +"negatív az értéke, a betűméret csökkenni fog." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:125 msgid "" @@ -1086,6 +1089,8 @@ msgstr "Szerző a fájl metaadataiban. Alapértelmezés: %default" msgid "" "Path to output file. By default a file is created in the current directory." msgstr "" +"A kimeneti fájl útvonala. Alapértelmezés szerint az aktuális könyvtárba " +"kerül a fájl." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Number of colors for grayscale image conversion. Default: %default" @@ -1134,6 +1139,8 @@ msgid "" "Don't sort the files found in the comic alphabetically by name. Instead use " "the order they were added to the comic." msgstr "" +"A képregény csomagban talált fájlokat a képregényhez való hozzáadás " +"sorrendje alapján rendezze a névsorrend helyett." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:317 msgid "" @@ -1185,6 +1192,10 @@ msgid "" " \n" "%prog converts mybook.epub to mybook.lrf" msgstr "" +"Használat: %prog [beállítások] konyv.epub\n" +" \n" +" \n" +"A %prog a konyv.epub fájlt lrf formátumba konvertálja." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 msgid "" @@ -1205,7 +1216,7 @@ msgstr "A létrehozott HTML kiírása a kimenetre, majd kilépés." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:30 msgid "Keep generated HTML files after completing conversion to LRF." -msgstr "" +msgstr "Ne törölje a konvertálásnál keletkező átmeneti HTML fájlokat." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 msgid "Options to control the behavior of feeds2disk" @@ -1225,7 +1236,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:319 msgid "\tParsing HTML..." -msgstr "" +msgstr "\tHTML beolvasása..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:342 msgid "\tBaen file detected. Re-parsing..." @@ -1241,71 +1252,79 @@ msgstr "Feldolgozás: %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:390 msgid "\tConverting to BBeB..." -msgstr "" +msgstr "\tKonvertálás BBeB formátumba..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:536 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:549 msgid "Could not parse file: %s" -msgstr "" +msgstr "Nem tudtam feldolgozni a fájlt: %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:541 msgid "%s is an empty file" -msgstr "" +msgstr "A %s fájl üres!" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:561 msgid "Failed to parse link %s %s" -msgstr "" +msgstr "A link feldolgozása nem sikerült: %s %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:605 msgid "Cannot add link %s to TOC" -msgstr "" +msgstr "Nem tudtam a linket hozzáadni a tartalomjegyzékhez: %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:957 msgid "Unable to process image %s. Error: %s" -msgstr "" +msgstr "Hiba a \"%s\" kép feldolgozása közben: %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:995 msgid "Unable to process interlaced PNG %s" -msgstr "" +msgstr "Nem tudtam feldolgozni a PNG képet: %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1010 msgid "" "Could not process image: %s\n" "%s" msgstr "" +"Nem tudtam feldolgozni a képet: %s\n" +"%s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1763 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" +"Hiba történt a táblázat feldolgozása közben: %s. A táblázat formázást " +"figyelmen kívül hagyom." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1765 msgid "" "Bad table:\n" "%s" msgstr "" +"Hibás táblázat:\n" +"%s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1787 msgid "Table has cell that is too large" -msgstr "" +msgstr "A táblázatban olyan cellák vannak, amelyek túl nagyok." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1817 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." msgstr "" +"Mentsd le a %s weboldalt egy mappába, majd a html fájlon futtasd a html2lrf " +"konvertáló programot." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1860 msgid "Could not read cover image: %s" -msgstr "" +msgstr "Nem tudtam a borító képet olvasni: %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1863 msgid "Cannot read from: %s" -msgstr "" +msgstr "Hiba olvasás közben: %s" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1988 msgid "Failed to process opf file" -msgstr "" +msgstr "Hiba az opf fájl feldolgozása közben" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1994 msgid "" @@ -1317,6 +1336,13 @@ msgid "" "to local files recursively. Thus, you can use it to \n" "convert a whole tree of HTML files." msgstr "" +"Használat: %prog [beállítások] konyv.html\n" +"\n" +"\n" +"A %prog a konyv.html fájlt LRF formátumba konvertálja. \n" +"A %prog minden linket rekurzívan követ ami helyi \n" +"html fájlokra hivatkozik, tehát lehetséges sok összefüggő \n" +"html fájl konvertálása is." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lit/convert_from.py:15 msgid "" @@ -1325,16 +1351,22 @@ msgid "" "\n" "%prog converts mybook.lit to mybook.lrf" msgstr "" +"Használat: %prog [beállítások] konyv.lit\n" +"\n" +"\n" +"A %prog a konyv.lit fájlt LRF formátumba konvertálja" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:136 msgid "" "%prog book.lrf\n" "Convert an LRF file into an LRS (XML UTF-8 encoded) file" msgstr "" +"%prog konyv.lrf\n" +"A prog a konyv.lrf fájlt LRS formátumba (UTF-8 kódolású XML) konvertálja." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:137 msgid "Output LRS file" -msgstr "" +msgstr "Kimeneti LRS fájl" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:139 msgid "Do not save embedded image and font files to disk" @@ -1342,42 +1374,44 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:158 msgid "Parsing LRF..." -msgstr "" +msgstr "LRF fájl beolvasása..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:161 msgid "Creating XML..." -msgstr "" +msgstr "XML létrehozása..." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:163 msgid "LRS written to " -msgstr "" +msgstr "Az LRS fájl helye: " #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:249 msgid "Could not read from thumbnail file:" -msgstr "" +msgstr "Nem tudtam az ikon fájlt olvasni:" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:269 msgid "" "%prog [options] file.lrs\n" "Compile an LRS file into an LRF file." msgstr "" +"%prog [beállítások] konyv.lrf\n" +"LRS fájlt lefordítása LRF formátumba." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:270 msgid "Path to output file" -msgstr "" +msgstr "A célfájl elérési útja" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:115 msgid "Verbose processing" -msgstr "" +msgstr "Informatívabb üzenetek feldolgozásnál" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274 msgid "Convert LRS to LRS, useful for debugging." -msgstr "" +msgstr "LRS fájl konvertálása LRS formátumba (hibakeresésnél hasznos)." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:455 msgid "Invalid LRF file. Could not set metadata." -msgstr "" +msgstr "Érvénytelen LRF fájl. Nem tudtam a metadatokat beállítani." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:580 msgid "" @@ -1391,42 +1425,44 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:43 msgid "Set the book title" -msgstr "" +msgstr "A könyv címe" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:589 msgid "Set sort key for the title" -msgstr "" +msgstr "Rendezési kulcs a címhez" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:591 msgid "Set the author" -msgstr "" +msgstr "Szerző" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:593 msgid "Set sort key for the author" -msgstr "" +msgstr "Rendezési kulcs a szerzőhöz" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:47 msgid "The category this book belongs to. E.g.: History" -msgstr "" +msgstr "A kategória, amibe a könyv tartozik. Pl.: történelem" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:598 msgid "Path to a graphic that will be set as this files' thumbnail" -msgstr "" +msgstr "A fájlhoz használandó ikon elérési útja" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:601 msgid "" "Path to a txt file containing the comment to be stored in the lrf file." msgstr "" +"A txt fájl útvonala, amelynek tartalma az lrf fájlhoz lesz csatolva " +"megjegyzésként." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:605 msgid "Extract thumbnail from LRF file" -msgstr "" +msgstr "Ikon kinyerése az LRF fájlból" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:606 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:182 msgid "Set the publisher" -msgstr "" +msgstr "Kiadó" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:607 msgid "Set the book classification" diff --git a/src/calibre/translations/it.po b/src/calibre/translations/it.po index 75aa8b10f5..7a4e1ae2ca 100644 --- a/src/calibre/translations/it.po +++ b/src/calibre/translations/it.po @@ -15,7 +15,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" diff --git a/src/calibre/translations/nb.po b/src/calibre/translations/nb.po index be714ffcf9..73084f46f8 100644 --- a/src/calibre/translations/nb.po +++ b/src/calibre/translations/nb.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/nds.po b/src/calibre/translations/nds.po index 7a7cfceb52..5e8c957481 100644 --- a/src/calibre/translations/nds.po +++ b/src/calibre/translations/nds.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" diff --git a/src/calibre/translations/nl.po b/src/calibre/translations/nl.po index a9e9f4a531..da5dacfa7a 100644 --- a/src/calibre/translations/nl.po +++ b/src/calibre/translations/nl.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/pl.po b/src/calibre/translations/pl.po index 027e0e3872..0ffeaa8b2d 100644 --- a/src/calibre/translations/pl.po +++ b/src/calibre/translations/pl.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/pt.po b/src/calibre/translations/pt.po index d64ad8338a..2ae167dfc0 100644 --- a/src/calibre/translations/pt.po +++ b/src/calibre/translations/pt.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/ro.po b/src/calibre/translations/ro.po index 0e7e3d5fe7..dcbd506b42 100644 --- a/src/calibre/translations/ro.po +++ b/src/calibre/translations/ro.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/ru.po b/src/calibre/translations/ru.po index 3eea9269da..b028b906ca 100644 --- a/src/calibre/translations/ru.po +++ b/src/calibre/translations/ru.po @@ -13,7 +13,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" "X-Poedit-Country: RUSSIAN FEDERATION\n" "X-Poedit-Language: Russian\n" diff --git a/src/calibre/translations/sk.po b/src/calibre/translations/sk.po index 432d0cf022..589b041657 100644 --- a/src/calibre/translations/sk.po +++ b/src/calibre/translations/sk.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/sl.po b/src/calibre/translations/sl.po index 099c7a69a0..5e50eb19b5 100644 --- a/src/calibre/translations/sl.po +++ b/src/calibre/translations/sl.po @@ -13,7 +13,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" diff --git a/src/calibre/translations/sv.po b/src/calibre/translations/sv.po index 5a7dca0b6d..a44e19fb0b 100644 --- a/src/calibre/translations/sv.po +++ b/src/calibre/translations/sv.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/te.po b/src/calibre/translations/te.po index e3f92f7a5a..f5479f9477 100644 --- a/src/calibre/translations/te.po +++ b/src/calibre/translations/te.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-30 19:20+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 diff --git a/src/calibre/translations/zh.po b/src/calibre/translations/zh.po index f27b424e92..5e9ed48ca7 100644 --- a/src/calibre/translations/zh.po +++ b/src/calibre/translations/zh.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" -"POT-Creation-Date: 2009-01-10 01:19+0000\n" -"PO-Revision-Date: 2009-01-08 21:03+0000\n" +"POT-Creation-Date: 2009-01-27 01:54+0000\n" +"PO-Revision-Date: 2009-02-01 20:57+0000\n" "Last-Translator: irvenwindson <Yuexi.Chen@gmail.com>\n" "Language-Team: Simplified Chinese <zh_CN@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-01-14 19:36+0000\n" +"X-Launchpad-Export-Date: 2009-02-04 20:28+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 @@ -22,15 +22,15 @@ msgid "Does absolutely nothing" msgstr "什么的不做" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:44 -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:44 -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:492 -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:965 -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:978 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:71 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:497 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:989 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1002 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:77 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:79 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:81 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:86 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:300 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:295 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:61 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:95 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:97 @@ -39,43 +39,54 @@ msgstr "什么的不做" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:69 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/rtf/convert_from.py:179 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:70 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:196 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:226 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:199 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:229 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:274 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:232 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:255 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:277 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:45 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:47 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:76 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:78 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:87 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:89 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:145 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:334 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:449 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:819 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:820 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:12 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:36 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:66 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:477 #: /home/kovid/work/calibre/src/calibre/ebooks/odt/to_oeb.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:361 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:366 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:858 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:861 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:53 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:54 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:159 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:170 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:365 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:37 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:38 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:346 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:360 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:861 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:709 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:949 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:952 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:376 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:899 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:700 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:942 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:945 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:61 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:123 #: /home/kovid/work/calibre/src/calibre/library/cli.py:257 #: /home/kovid/work/calibre/src/calibre/library/database.py:920 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1404 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1435 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1464 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1592 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:461 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1405 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1434 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1468 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1594 #: /home/kovid/work/calibre/src/calibre/library/database2.py:473 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:808 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:841 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:485 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:828 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:861 msgid "Unknown" msgstr "未知状态" @@ -124,19 +135,18 @@ msgstr "从动画文件中提取封面" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:186 msgid "Read metadata from ebooks in ZIP archives" -msgstr "" +msgstr "从ZIP文件中的电子书籍读取metadata" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:196 -msgid "Set metadata in EPUB files" -msgstr "设置EPUB文件的metadata" +msgid "Read metadata from ebooks in RAR archives" +msgstr "从RAR压缩文件中的电子书籍读取metadata" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:206 -msgid "Set metadata in LRF files" -msgstr "设置LRF文件的metadata" - -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:216 -msgid "Set metadata in RTF files" -msgstr "设置RTF文件的metadata" +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:207 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:217 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:227 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:237 +msgid "Set metadata in %s files" +msgstr "设置 %s 文件的metadata" #: /home/kovid/work/calibre/src/calibre/customize/ui.py:28 msgid "Installed plugins" @@ -200,40 +210,42 @@ msgstr "启用指名的插件" msgid "Disable the named plugin" msgstr "禁用指名的插件" -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:140 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:158 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:196 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:224 -#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:182 -#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:223 -#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:250 -msgid "Unable to detect the %s disk drive. Try rebooting." -msgstr "无法侦测到 %s 磁盘, 请重新启动后重试." - -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:412 -#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:51 +#: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:41 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:384 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:70 msgid "The reader has no storage card connected." msgstr "该阅读器未连接存储卡." -#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:62 +#: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:60 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:89 msgid "There is insufficient free space on the storage card" -msgstr "" +msgstr "存储卡上的空间不足" -#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:64 +#: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:62 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:91 msgid "There is insufficient free space in main memory" -msgstr "" +msgstr "设备内置存储空间不足" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:92 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:140 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:167 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:195 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:191 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:227 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:254 +msgid "Unable to detect the %s disk drive. Try rebooting." +msgstr "无法侦测到 %s 磁盘, 请重新启动后重试." + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:94 msgid "Options to control the conversion to EPUB" msgstr "EPUB文件转换控制选项" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:103 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 msgid "" "The output EPUB file. If not specified, it is derived from the input file " "name." msgstr "EPUB输出文件名. 如不指明, 使用与输入文件相同的主文件名." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:107 msgid "" "Profile of the target device this EPUB is meant for. Set to None to create a " "device independent EPUB. The profile is used for device specific " @@ -242,17 +254,17 @@ msgstr "" "设置EPUB文件的目标设备文件的属性Profile. 对于无设备依赖的EPUB文件设置为None. 该Profile使EPUB文件适应设备限制. " "选项有: " -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:109 msgid "" "Either the path to a CSS stylesheet or raw CSS. This CSS will override any " "existing CSS declarations in the source files." msgstr "设定CSS样式或者raw CSS的路径. 该CSS样式将覆盖源文件中所声明的CSS样式." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 msgid "Control auto-detection of document structure." msgstr "设置自动检测文档结构." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 msgid "" "An XPath expression to detect chapter titles. The default is to consider " "<h1> or\n" @@ -272,7 +284,7 @@ msgstr "" "从calibre用户指南中关于XPath标签列表部分获得更多的该\n" "功能信息.\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:119 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:121 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 " @@ -282,17 +294,17 @@ msgstr "" "设置标注章节的模式. \"pagebreak\"模式会在章节前插入下一页控制符. \"rule\"模式会在章节前插入空行. " "\"none\"模式不会在章节前插入控制. \"both\"模式会在章节前插入下一页控制符和空行." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:121 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:123 msgid "Path to the cover to be used for this book" msgstr "设置所使用的封面文件路径" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:124 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:126 msgid "" "Use the cover detected from the source file in preference to the specified " "cover." msgstr "使用从源文件中检测到的封面文件." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:128 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 " @@ -300,8 +312,10 @@ msgid "" "if your source file contains a very large number of page breaks, you should " "turn off splitting on page breaks." msgstr "" +"关闭按分页符切割. 默认情况下, 程序会按分页符将输入文件切切分为多个文件. 由此程序可以使用较少的计算机资源来解析和输出结果. " +"当然切分操作会增加处理时间, 如果输入文件含有较多的分页符, 请关闭此功能." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:128 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:130 msgid "" "Control the automatic generation of a Table of Contents. If an OPF file is " "detected\n" @@ -313,38 +327,38 @@ msgstr "" "包含文件目录信息, 则使用OPF文件内容作为文件目录\n" "而不使用自动生成的文件目录.\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:136 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 --toc-" "threshold number of chapters were detected." msgstr "文件目录中链接的最大值. 0表示无最大值限制. 默认值为 %default . 如果检测到的章节少于该默认值, 则是用实际检测到的值." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:138 msgid "Don't add auto-detected chapters to the Table of Contents." msgstr "不要将检测到的章节添加到文件目录中作为链接." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:140 msgid "" "If fewer than this number of chapters is detected, then links are added to " "the Table of Contents. Default: %default" msgstr "如果少于默认上限的章节数被检测到, 这些章节的链接将被添加到文件目录. 默认值; %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:142 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 "用XPath表达式设置将被添加到文件第一级目录的标签. 该选项将关闭其他的对应自动检测功能." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:144 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 "用XPath表达式设置将被添加到文件第二级目录的标签. 这些第二级目录将被添加到上一个第一级目录下方." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:144 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:146 msgid "" "Path to a .ncx file that contains the table of contents to use for this " "ebook. The NCX file should contain links relative to the directory it is " @@ -354,46 +368,46 @@ msgstr "" "设置包含目录信息的.ncx文件路径. NCX文件应该使用相对路径链接来表示目录信息. " "从http://www.niso.org/workrooms/daisy/Z39-86-2005.html#NCX获取关于NCX文件格式信息." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:148 msgid "" "Normally, if the source file already has a Table of Contents, it is used in " "preference to the autodetected one. With this option, the autodetected one " "is always used." msgstr "设置一直使用自动检测生成文件目录. 通常情况下, 如源文件含有文件目录信息, 软件会使用源文件目录信息而不使用自动检测生成目录功能." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:148 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:150 msgid "Control page layout" msgstr "页面布局控制" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:150 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:152 msgid "Set the top margin in pts. Default is %default" msgstr "设置页首边界, 单位pts. 默认值为 %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:152 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:154 msgid "Set the bottom margin in pts. Default is %default" msgstr "设置页尾边界, 单位pts. 默认值为 %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:156 msgid "Set the left margin in pts. Default is %default" msgstr "设置页面左边界, 单位pts. 默认值为 %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:158 msgid "Set the right margin in pts. Default is %default" msgstr "设置页面右边界, 单位pts. 默认值为 %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:158 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:160 msgid "" "The base font size in pts. Default is %defaultpt. Set to 0 to disable " "rescaling of fonts." msgstr "设置基本字体大小, 单位pts. 默认值为 %defaultpt . 设置为0来禁用重设字体." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:160 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:162 msgid "" "Remove spacing between paragraphs. Will not work if the source file forces " "inter-paragraph spacing." msgstr "移除段落之间的空格. 如果源文件被设定强制使用段落间隔, 该功能将无效." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:164 msgid "" "Preserve the HTML tag structure while splitting large HTML files. This is " "only neccessary if the HTML files contain CSS that uses sibling selectors. " @@ -402,36 +416,39 @@ msgstr "" "在分割较大的HTML文件时保留HTML标签. 该功能仅在切割含有相邻选择器(Sibling Selector)的HTML文件时有用. " "开启该选项将大幅增加处理较大的HTML文件时所需时间." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:167 msgid "Print generated OPF file to stdout" msgstr "打印生成的OPF文件到标准输出" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:169 msgid "Print generated NCX file to stdout" msgstr "打印生成的NCX文件到标准输出" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:169 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:171 msgid "Keep intermediate files during processing by html2epub" msgstr "在进行html2epub转换时保留中间过程文件" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:171 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:173 msgid "" "Extract the contents of the produced EPUB file to the specified directory." msgstr "从生成的EPUB文件中提取出的内容到文件夹." -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:184 msgid "" "%%prog [options] filename\n" "\n" "Convert any of a large number of ebook formats to a %s file. Supported " "formats are: %s\n" -msgstr "%%prog [options] filename\n" +msgstr "" +"%%prog [options] filename\n" +"\n" +"转换不同电子书籍格式到 %s 文件. 支持的格式有: %s\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:100 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:102 msgid "Could not find an ebook inside the archive" msgstr "无法在压缩文件中找到电子书籍" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:214 msgid "" "%prog [options] file.html|opf\n" "\n" @@ -447,13 +464,14 @@ msgstr "" "如果指明OPF文件, 则使用从OPF文件中获得的<spine>元素\n" "而不使用HTML文件中的链接. \n" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:413 -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:739 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:465 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:746 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:589 msgid "Output written to " msgstr "输出文件写入到 " -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:435 -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1063 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:487 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1087 msgid "You must specify an input HTML file" msgstr "您必须设定输入HTML文件" @@ -466,93 +484,94 @@ msgid "" "Could not find reasonable point at which to split: %s Sub-tree size: %d KB" msgstr "无法找到合理的切分点: %s 子树大小: %d KB" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:142 msgid "" "\t\tToo much markup. Re-splitting without structure preservation. This may " "cause incorrect rendering." msgstr "\t\t过多的描述标签.重新进行切分并不保留结构.这可能会造成排版变形." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:504 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:509 msgid "Written processed HTML to " msgstr "将处理后的HTML文件写入 " -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:848 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:872 msgid "Options to control the traversal of HTML" msgstr "控制HTML遍历方式的选项" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:855 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:879 msgid "The output directory. Default is the current directory." msgstr "输出文件夹.默认为当前文件夹." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:857 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:881 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:537 msgid "Character encoding for HTML files. Default is to auto detect." msgstr "HTML文件的编码.默认为自动检测." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:859 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:883 msgid "" "Create the output in a zip file. If this option is specified, the --output " "should be the name of a file not a directory." msgstr "输出到一个zip压缩文件.如果打开该选项, --output应该指明文件名而非目录." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:861 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:885 msgid "Control the following of links in HTML files." msgstr "处理HTML文件链接的选项." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:863 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:887 msgid "" "Traverse links in HTML files breadth first. Normally, they are traversed " "depth first" msgstr "HTML链接遍历使用广度优先模式. 程序默认使用深度优先遍历模式" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:865 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:889 msgid "" "Maximum levels of recursion when following links in HTML files. Must be non-" "negative. 0 implies that no links in the root HTML file are followed." msgstr "HTML链接遍历深度. 必须为非负整数. 0表示不遍历根HTML文件中的人和链接." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:867 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:891 msgid "Set metadata of the generated ebook" msgstr "设置生成电子书籍的metadata" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:869 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:893 msgid "Set the title. Default is to autodetect." msgstr "设置书名. 默认为自动检测." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:871 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:895 msgid "The author(s) of the ebook, as a comma separated list." msgstr "电子书籍的作者, 用分号隔开多个作者名字." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:873 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:897 msgid "The subject(s) of this book, as a comma separated list." msgstr "电子书籍的主题, 用分号隔开多个主题项." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:875 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:899 msgid "Set the publisher of this book." msgstr "设置电子书籍的出版商名称." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:877 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:901 msgid "A summary of this book." msgstr "电子书籍的摘要." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:879 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:903 msgid "Load metadata from the specified OPF file" msgstr "从设定的OPF文件中获取metadata" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:881 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:905 msgid "Options useful for debugging" msgstr "用于调试的选项" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:883 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:907 msgid "" "Be more verbose while processing. Can be specified multiple times to " "increase verbosity." msgstr "在进行处理时打印更多的信息. 可以设置打印信息的级数." -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:885 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:909 msgid "Output HTML is \"pretty printed\" for easier parsing by humans" msgstr "输出较好格式化的HTML文件以供手工处理" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:891 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:915 msgid "" "%prog [options] file.html|opf\n" "\n" @@ -563,39 +582,47 @@ msgid "" "element\n" "is used.\n" msgstr "" +"%prog [options] file.html|opf\n" +"\n" +"保留所有HTML文件的链接并将其引用的资源整理到指明文件夹.\n" +"保留整理图片, 样式表, 脚本等等资源. \n" +"如果指明OPF文件, 使用<spine>元素中指明的文件列表.\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/from_any.py:44 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/from_any.py:47 msgid "Creating LIT file from EPUB..." msgstr "从EPUB文件创建LIT文件..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:849 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:852 msgid "%prog [options] LITFILE" msgstr "%prog [options] LITFILE" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:852 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:475 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:855 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:501 msgid "Output directory. Defaults to current directory." msgstr "输出文件夹. 默认为当前文件夹." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:855 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:858 msgid "Legibly format extracted markup. May modify meaningful whitespace." msgstr "简化检测到的修饰元素. 可能会删除有用的空格符号." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:858 -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:724 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:861 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:719 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:549 msgid "Useful for debugging." msgstr "调试信息." -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:869 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:499 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:872 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:525 msgid "OEB ebook created in" msgstr "创建OEB电子书籍到" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:718 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:713 msgid "%prog [options] OPFFILE" msgstr "%prog [options] OPFFILE" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:721 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:716 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/from_feeds.py:26 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:546 msgid "Output file. Default is derived from input filename." msgstr "输出文件. 默认使用与输入文件相同的文件名." @@ -626,7 +653,7 @@ msgid "Sort key for the author" msgstr "作者排序" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:87 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:275 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:278 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:108 msgid "Publisher" @@ -685,7 +712,7 @@ msgstr "设置页眉格式. %a 表示作者 %t 表示书名. 默认值为 %defau #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:112 msgid "Add extra spacing below the header. Default is %default px." -msgstr "" +msgstr "在页首后加入额外的空行间隔. 默认为 %default px." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:114 msgid "" @@ -917,15 +944,15 @@ msgstr "" msgid "No file to convert specified." msgstr "未指明待转换的源文件." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:229 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:224 msgid "Rendered %s" msgstr "输出 %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:232 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:227 msgid "Failed %s" msgstr "处理 %s 失败" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:284 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:279 msgid "" "Failed to process comic: %s\n" "\n" @@ -935,72 +962,72 @@ msgstr "" "\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:291 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:286 msgid "" "Options to control the conversion of comics (CBR, CBZ) files into ebooks" msgstr "转换动画文件(CBR, CBZ)到电子书籍的选项" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:292 msgid "Title for generated ebook. Default is to use the filename." msgstr "生成电子书籍的书名. 默认使用源文件名." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:294 msgid "" "Set the author in the metadata of the generated ebook. Default is %default" msgstr "设置生成电子书籍的作者metadata数据. 默认值为 %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:302 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:297 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:22 msgid "" "Path to output file. By default a file is created in the current directory." msgstr "输出文件路径. 默认输出文件夹为当前文件夹." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:304 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:299 msgid "Number of colors for grayscale image conversion. Default: %default" msgstr "转化输出图片的灰度阶数. 默认值: %default" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:306 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:301 msgid "" "Disable normalize (improve contrast) color range for pictures. Default: False" msgstr "禁用图片色阶规范化(提升图片对比度). 默认: 关闭" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:308 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:303 msgid "Maintain picture aspect ratio. Default is to fill the screen." msgstr "维持图片长宽比例. 默认为缩放至屏幕大小." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:310 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:305 msgid "Disable sharpening." msgstr "禁用锐利化." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:312 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:307 msgid "Don't split landscape images into two portrait images" msgstr "不要将横向图片分割为两张纵向图片" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:314 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:309 msgid "" "Keep aspect ratio and scale image using screen height as image width for " "viewing in landscape mode." msgstr "在将纵向图片旋转缩放到横向浏览模式时保持长宽比." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:316 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:311 msgid "" "Used for right-to-left publications like manga. Causes landscape pages to be " "split into portrait pages from right to left." msgstr "开启从右至左的漫画切分模式. 该功能会将横向图片页面且分为多个从右至左的纵向页面." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:313 msgid "" "Enable Despeckle. Reduces speckle noise. May greatly increase processing " "time." msgstr "开启除噪点功能. 该功能将去除噪点. 可能会大幅度增加处理时间." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:320 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:315 msgid "" "Don't sort the files found in the comic alphabetically by name. Instead use " "the order they were added to the comic." msgstr "不要按照文件名字母排序动画文件列表. 而使用文件被添加的顺序." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:322 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:317 msgid "" "Choose a profile for the device you are generating this file for. The " "default is the SONY PRS-500 with a screen size of 584x754 pixels. This is " @@ -1009,22 +1036,22 @@ msgstr "" "选择生成电子书籍的目标设备属性profile. 默认选项为SONY PRS-500阅读器,屏幕尺寸 584x754 像素. " "这个profile适合于带有相同屏幕分辨率的阅读设备. 选择为 %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:324 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:319 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:20 msgid "" "Be verbose, useful for debugging. Can be specified multiple times for " "greater verbosity." msgstr "处理时打印信息, 对于调试有用. 可以设置打印信息的级数." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:326 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:321 msgid "Don't show progress bar." msgstr "不要显示进度条." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:329 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:324 msgid "Apply no processing to the image" -msgstr "" +msgstr "不对图片进行处理" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:334 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:329 msgid "" "%prog [options] comic.cb[z|r]\n" "\n" @@ -1034,11 +1061,12 @@ msgstr "" "\n" "转换CBZ或CBR漫画到电子书籍. \n" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:394 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:389 msgid "Output written to" msgstr "输出到" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:459 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:549 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/from_comic.py:35 msgid "Rendering comic pages..." msgstr "正在处理漫画页面..." @@ -1087,56 +1115,56 @@ msgstr "控制html2lrf行为的选项" msgid "Fetching of recipe failed: " msgstr "无法获得转换方式: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:313 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:317 msgid "\tBook Designer file detected." msgstr "\t检测到Book Designer文件." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:315 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:319 msgid "\tParsing HTML..." msgstr "\t正在处理HTML文件..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:338 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:342 msgid "\tBaen file detected. Re-parsing..." msgstr "\t检测到Baen文件. 重新分析处理中..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:354 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:358 msgid "Written preprocessed HTML to " msgstr "输出预处理HTML文件到 " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:372 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:376 msgid "Processing %s" msgstr "正在处理 %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:386 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:390 msgid "\tConverting to BBeB..." msgstr "\t转换到BBeB文件中..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:532 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:545 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:536 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:549 msgid "Could not parse file: %s" msgstr "无法分析处理文件: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:537 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:541 msgid "%s is an empty file" msgstr "%s 是一个空文件" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:557 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:561 msgid "Failed to parse link %s %s" msgstr "处理链接失败 %s %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:601 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:605 msgid "Cannot add link %s to TOC" msgstr "无法将链接 %s 添加到文件目录" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:953 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:957 msgid "Unable to process image %s. Error: %s" msgstr "无法处理图片 %s. 错误: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:991 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:995 msgid "Unable to process interlaced PNG %s" msgstr "无法处理隔行模式PNG文件 %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1006 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1010 msgid "" "Could not process image: %s\n" "%s" @@ -1144,12 +1172,12 @@ msgstr "" "无法处理图片: %s\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1759 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1763 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "处理以下表格时发生错误: %s. 忽略该表格样式." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1761 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1765 msgid "" "Bad table:\n" "%s" @@ -1157,29 +1185,29 @@ msgstr "" "错误表格格式的:\n" "%s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1783 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1787 msgid "Table has cell that is too large" msgstr "表格含有过大的单元格" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1813 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1817 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." msgstr "您必须首先将站点 %s 存储为HTML文件后再运行html2lrf." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1856 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1860 msgid "Could not read cover image: %s" msgstr "无法转换图片: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1859 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1863 msgid "Cannot read from: %s" msgstr "无法从源读取: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1984 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1988 msgid "Failed to process opf file" msgstr "处理opf文件失败" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1990 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1994 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -1223,7 +1251,7 @@ msgstr "输出LRS文件" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:139 msgid "Do not save embedded image and font files to disk" -msgstr "" +msgstr "不要存储内嵌图片和字体" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:158 msgid "Parsing LRF..." @@ -1281,7 +1309,7 @@ msgstr "" "\n" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:587 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:43 msgid "Set the book title" msgstr "设置电子书籍的书名" @@ -1298,7 +1326,7 @@ msgid "Set sort key for the author" msgstr "设置作者排序键" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:44 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:47 msgid "The category this book belongs to. E.g.: History" msgstr "设置电子书籍的类型. 例如: 历史" @@ -1316,20 +1344,21 @@ msgid "Extract thumbnail from LRF file" msgstr "从LRF文件中提取预览" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:606 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:182 msgid "Set the publisher" -msgstr "" +msgstr "设置出版商" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:607 msgid "Set the book classification" -msgstr "" +msgstr "设置书籍分类" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:608 msgid "Set the book creator" -msgstr "" +msgstr "设置书籍的创建者" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:609 msgid "Set the book producer" -msgstr "" +msgstr "设置书籍的出版商" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:611 msgid "" @@ -1418,71 +1447,71 @@ msgstr "" "\n" "%prog 转换mybook.txt到mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:42 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:45 msgid "Set the authors" msgstr "设置作者信息" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:46 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:49 msgid "Set the comment" msgstr "设置注释信息" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:273 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:276 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:69 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:70 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:36 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:103 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:343 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:931 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:969 msgid "Title" msgstr "书名" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:274 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:277 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:104 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:348 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:932 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:970 msgid "Author(s)" msgstr "作者" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:276 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:279 msgid "Producer" msgstr "出品人" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:277 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:493 msgid "Category" msgstr "类别" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:278 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:281 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:71 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:64 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:394 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:535 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:338 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:304 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:432 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:320 #: /home/kovid/work/calibre/src/calibre/gui2/status.py:58 msgid "Comments" msgstr "注释" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:280 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:283 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:109 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:293 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:871 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:309 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:909 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:973 #: /home/kovid/work/calibre/src/calibre/gui2/status.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 msgid "Tags" msgstr "标签" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:281 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:284 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:110 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:309 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:325 #: /home/kovid/work/calibre/src/calibre/gui2/status.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 msgid "Series" msgstr "系列" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:282 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:285 msgid "Language" msgstr "语言" @@ -1586,15 +1615,28 @@ msgstr "" "\n" "通过书籍的ISBN从LibraryThing.com获得书籍的封面图片\n" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:40 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:35 msgid "Usage: %s file.lit" msgstr "用法: %s file.lit" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:50 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/lit.py:45 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:227 msgid "Cover saved to" msgstr "存储封面到" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:964 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:178 +msgid "Set the subject tags" +msgstr "设置主题标签" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:180 +msgid "Set the language" +msgstr "设置语言标签" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:184 +msgid "Set the ISBN" +msgstr "设置ISBN" + +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:965 msgid "Set the dc:language field" msgstr "设置 dc:language 栏目" @@ -1604,45 +1646,170 @@ msgstr "用法: pdf-meta file.pdf" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rb.py:59 msgid "Usage: rb-meta file.rb" -msgstr "" +msgstr "用法: rb-meta file.rb" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:473 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/from_any.py:55 +msgid "Creating Mobipocket file from EPUB..." +msgstr "从EPUB文件转换到Mobipocket文件中..." + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:499 msgid "%prog [options] myebook.mobi" +msgstr "%prog [options] myebook.mobi" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:523 +msgid "Raw MOBI HTML saved in" +msgstr "Raw MOBI HTML 保存" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:512 +msgid "Options to control the conversion to MOBI" +msgstr "控制转换到MOBI格式的选项" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:519 +msgid "Mobipocket-specific options." +msgstr "Mobipocket相关选项." + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:521 +msgid "" +"Compress file text using PalmDOC compression. Results in smaller files, but " +"takes a long time to run." +msgstr "使用PalmDOC压缩模式压缩文件文本. 可以减小文件体积, 但会增加处理时间." + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:524 +msgid "Modify images to meet Palm device size limitations." +msgstr "缩放图片使之适应Palm设备的屏幕尺寸." + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:526 +msgid "Title for any generated in-line table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:497 -msgid "Raw MOBI HTML saved in" +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:527 +msgid "" +"Device renderer profiles. Affects conversion of font sizes, image rescaling " +"and rasterization of tables. Valid profiles are: %s." msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:532 +msgid "Source renderer profile. Default is %default." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:535 +msgid "Destination renderer profile. Default is %default." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:543 +msgid "[options]" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:561 +msgid "Unknown source profile %r" +msgstr "未知的源配置文件 %r" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:565 +msgid "Unknown destination profile %r" +msgstr "未知的目标配置文件 %r" + #: /home/kovid/work/calibre/src/calibre/ebooks/odt/to_oeb.py:57 msgid "The output directory. Defaults to the current directory." +msgstr "输出文件夹. 默认为输出到当前文件夹." + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:586 +msgid "Cover" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:587 +msgid "Title Page" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:588 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/htmltoc.py:18 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:47 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:160 +msgid "Table of Contents" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:589 +msgid "Index" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:590 +msgid "Glossary" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:591 +msgid "Acknowledgements" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:592 +msgid "Bibliography" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:593 +msgid "Colophon" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:594 +msgid "Copyright" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:595 +msgid "Dedication" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:596 +msgid "Epigraph" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:597 +msgid "Foreword" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:598 +msgid "List of Illustrations" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:599 +msgid "List of Tables" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:600 +msgid "Notes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:601 +msgid "Preface" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:602 +msgid "Main Text" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:13 msgid "Options to control the transformation of pdf" -msgstr "" +msgstr "控制PDF转换的选项" #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:24 msgid "Number of pixels to crop from the left most x (default is %d) " -msgstr "" +msgstr "页面左部切边宽度像素值 x (默认值为 %d) " #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:26 msgid "Number of pixels to crop from the left most y (default is %d) " -msgstr "" +msgstr "页面左部切边宽度像素值 y (默认值为 %d) " #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:28 msgid "Number of pixels to crop from the right most x (default is %d) " -msgstr "" +msgstr "页面右部切边宽度像素值 x (默认值为 %d) " #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:30 msgid "Number of pixels to crop from the right most y (default is %d)" -msgstr "" +msgstr "页面右部切边宽度像素值 y (默认值为 %d)" #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:32 msgid "" "A file generated by ghostscript which allows each page to be individually " "cropped [gs -dSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox > bounding] " msgstr "" +"由ghostscript生成的可按页单独切边的文件 [gs -dSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox > " +"bounding] " #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:38 msgid "" @@ -1651,584 +1818,602 @@ msgid "" "\tCrops a pdf. \n" "\t" msgstr "" +"\t%prog [options] file.pdf\n" +"\n" +"\t对PDF文件切边. \n" +"\t" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:25 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:427 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:433 msgid "Frequently used directories" -msgstr "" +msgstr "常用的目录列表" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:27 msgid "Send file to storage card instead of main memory by default" -msgstr "" +msgstr "默认将文件传输到扩展卡而非设备内置存储" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:29 msgid "The format to use when saving single files to disk" -msgstr "" +msgstr "存储单个文件时使用的格式" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:31 msgid "Confirm before deleting" -msgstr "" +msgstr "删除前要求用户确认" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:33 msgid "Toolbar icon size" -msgstr "" +msgstr "工具栏图标大小" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:35 msgid "Show button labels in the toolbar" -msgstr "" +msgstr "在工具栏上显示文字标签" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:37 msgid "Main window geometry" -msgstr "" +msgstr "主窗口位置尺寸" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:39 msgid "Notify when a new version is available" -msgstr "" +msgstr "在程序有新版本时提示" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:41 msgid "Use Roman numerals for series number" -msgstr "" +msgstr "使用罗马数字作为序列数字" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:43 msgid "Sort tags list by popularity" -msgstr "" +msgstr "按欢迎度排序标签" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:45 msgid "Number of covers to show in the cover browsing mode" -msgstr "" +msgstr "在浏览模式下显示的书籍封面数量" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:47 msgid "Defaults for conversion to LRF" -msgstr "" +msgstr "转换到LRF文件的默认选项" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:49 msgid "Options for the LRF ebook viewer" -msgstr "" +msgstr "察看LRF文件的选项" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:51 msgid "Formats that are viewed using the internal viewer" -msgstr "" +msgstr "使用内置浏览器查看的文件格式" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:53 msgid "Columns to be displayed in the book list" -msgstr "" +msgstr "显示书籍列表时显示的信息列" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:54 msgid "Automatically launch content server on application startup" -msgstr "" +msgstr "在程序启动时启动内容服务器程序" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:55 msgid "Oldest news kept in database" -msgstr "" +msgstr "在数据库中保留旧消息" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:56 msgid "Show system tray icon" -msgstr "" +msgstr "显示系统托盘图标" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:58 msgid "Upload downloaded news to device" -msgstr "" +msgstr "将下载的新闻传输到设备上" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:60 msgid "Delete books from library after uploading to device" -msgstr "" +msgstr "将书籍传输到设备后从书库中删除" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:62 msgid "" "Show the cover flow in a separate window instead of in the main calibre " "window" +msgstr "将封面显示在单独的窗口而不是在calibre主窗口" + +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:64 +msgid "Disable notifications from the system tray icon" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/device.py:72 msgid "Device no longer connected." -msgstr "" +msgstr "设备未联机." #: /home/kovid/work/calibre/src/calibre/gui2/device.py:117 msgid "Get device information" -msgstr "" +msgstr "获取设备信息" #: /home/kovid/work/calibre/src/calibre/gui2/device.py:128 msgid "Get list of books on device" -msgstr "" +msgstr "从设备上读取书籍列表" #: /home/kovid/work/calibre/src/calibre/gui2/device.py:137 msgid "Send metadata to device" -msgstr "" +msgstr "传输metadata到设备上" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:146 msgid "Upload %d books to device" -msgstr "" +msgstr "上传 %d 书籍到设备上" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:159 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:161 msgid "Delete books from device" -msgstr "" +msgstr "从设备上删除书籍" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:176 msgid "Download books from device" -msgstr "" +msgstr "从设备上下载书籍" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:186 msgid "View book on device" -msgstr "" +msgstr "察看设备上的书籍" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:84 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:85 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:86 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:300 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:866 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:904 #: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 msgid "Path" -msgstr "" +msgstr "路径" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:87 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:88 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:89 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:92 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:299 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:315 #: /home/kovid/work/calibre/src/calibre/gui2/status.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 msgid "Formats" -msgstr "" +msgstr "格式" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:61 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:88 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:48 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:52 msgid "Dialog" -msgstr "" +msgstr "对话框" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:62 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:63 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:41 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:50 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/warning_ui.py:53 msgid "TextLabel" -msgstr "" +msgstr "文字标签" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:65 msgid "&Previous" -msgstr "" +msgstr "上一个(&P)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:66 msgid "&Next" -msgstr "" +msgstr "下一个(&N)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:40 msgid "Choose Format" -msgstr "" +msgstr "选择格式" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:34 msgid "Set defaults for conversion of comics (CBR/CBZ files)" -msgstr "" +msgstr "设置漫画文件的转换选项 (CBR/CBZ files)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:49 msgid "Set options for converting %s" -msgstr "" +msgstr "设置转换 %s 的选项" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:89 msgid "&Title:" -msgstr "" +msgstr "标题(&T);" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:90 msgid "&Author(s):" -msgstr "" +msgstr "作者(&A):" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91 msgid "&Number of Colors:" -msgstr "" +msgstr "颜色数(&N):" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:401 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:440 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid "&Profile:" -msgstr "" +msgstr "配置文件(&P);" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:93 msgid "Disable &normalize" -msgstr "" +msgstr "关闭图像规范化(&n)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:94 msgid "Keep &aspect ratio" -msgstr "" +msgstr "保持宽高比(&a)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:95 msgid "Disable &Sharpening" -msgstr "" +msgstr "关闭锐化(&S)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 msgid "&Landscape" -msgstr "" +msgstr "横向(&L)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 msgid "Don't so&rt" -msgstr "" +msgstr "不要排序(&r)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 msgid "&Right to left" -msgstr "" +msgstr "从右向左(&R)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:99 msgid "De&speckle" -msgstr "" +msgstr "除噪点(&s)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:100 msgid "&Wide" -msgstr "" +msgstr "宽度(&W)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:100 msgid " plugins" -msgstr "" +msgstr " 插件" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:106 msgid "by" -msgstr "" +msgstr "由" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:123 msgid "Advanced" -msgstr "" +msgstr "高级" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:123 msgid "General" -msgstr "" +msgstr "常规" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:123 msgid "Interface" -msgstr "" +msgstr "界面" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:124 msgid "" "Content\n" "Server" msgstr "" +"内容\n" +"服务器" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:124 msgid "Plugins" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:256 -msgid "No valid plugin path" -msgstr "" +msgstr "插件" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:257 +msgid "No valid plugin path" +msgstr "不合法的插件路径" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:258 msgid "%s is not a valid plugin path" -msgstr "" +msgstr "%s 不是合法的插件路径" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:261 msgid "Choose plugin" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271 -msgid "Plugin cannot be disabled" -msgstr "" +msgstr "选择插件" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:272 -msgid "The plugin: %s cannot be disabled" -msgstr "" +msgid "Plugin cannot be disabled" +msgstr "该插件不能被禁用" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:282 -msgid "Plugin not customizable" -msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273 +msgid "The plugin: %s cannot be disabled" +msgstr "插件: %s 不能被禁用" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:283 +msgid "Plugin not customizable" +msgstr "无法个性化插件" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:284 msgid "Plugin: %s does not need customization" -msgstr "" +msgstr "插件: %s 无需个性化设置" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287 msgid "Customize %s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:296 -msgid "Cannot remove builtin plugin" -msgstr "" +msgstr "个性化 %s" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:297 +msgid "Cannot remove builtin plugin" +msgstr "不能移除内置插件" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:298 msgid " cannot be removed. It is a builtin plugin. Try disabling it instead." -msgstr "" +msgstr " 无法移除. 该插件是内置插件. 您可以尝试禁用它而非移除." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:318 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:319 msgid "Error log:" -msgstr "" +msgstr "错误日志:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:322 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:323 msgid "Access log:" -msgstr "" +msgstr "访问日志:" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:344 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:389 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:385 msgid "Failed to start content server" -msgstr "" +msgstr "无法启动内容服务器" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:384 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:385 msgid "Invalid size" -msgstr "" +msgstr "无效的尺寸" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:384 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:385 msgid "The size %s is invalid. must be of the form widthxheight" -msgstr "" +msgstr "尺寸大小 %s 不合法. 合法的格式为 宽度x高度" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:421 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:423 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:427 msgid "Invalid database location" -msgstr "" +msgstr "不合法的数据库路径" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:422 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:424 msgid "<br>Must be a directory." -msgstr "" +msgstr "<br>必须是文件目录." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:422 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:424 msgid "Invalid database location " -msgstr "" +msgstr "不合法的数据库路径 " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:426 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:428 msgid "Invalid database location.<br>Cannot write to " -msgstr "" +msgstr "不合法的数据库路径.<br>无法写入到 " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:438 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:440 msgid "Compacting database. This may take a while." -msgstr "" +msgstr "压缩数据库中. 请稍候." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:438 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:440 msgid "Compacting..." -msgstr "" +msgstr "压缩中..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:411 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:417 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:343 msgid "Configuration" -msgstr "" +msgstr "设置" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:412 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:418 msgid "" "&Location of ebooks (The ebooks are stored in folders sorted by author and " "metadata is stored in the file metadata.db)" -msgstr "" +msgstr "电子书籍的位置(&L) (电子书籍按作者排序存储在文件目录中而metadata存储在metadata.db数据库中)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:413 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:419 msgid "Browse for the new database location" -msgstr "" +msgstr "选择新的数据库路径" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:414 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:431 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:441 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:442 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:471 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:377 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:319 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:333 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:437 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:452 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:453 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:414 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:497 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:308 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:327 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:340 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:344 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:346 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:350 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:352 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:126 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:131 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:135 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:233 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:235 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:236 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:322 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:328 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:330 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:344 msgid "..." -msgstr "" +msgstr "..." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:415 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:421 msgid "Show notification when &new version is available" -msgstr "" +msgstr "在程序有新版本时提示(&n)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:416 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:422 msgid "" "If you disable this setting, metadata is guessed from the filename instead. " "This can be configured in the Advanced section." -msgstr "" +msgstr "如果您禁用本设置, metadata将从文件名中模糊获取. 您也可以在高级设置中配置此项." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:417 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:423 msgid "Read &metadata from files" -msgstr "" +msgstr "从文件中读取metadata(&m)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:424 msgid "Format for &single file save:" -msgstr "" +msgstr "单个文件存储格式(&s):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:425 msgid "Default network &timeout:" -msgstr "" +msgstr "默认网络超时(&t)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:426 msgid "" "Set the default timeout for network fetches (i.e. anytime we go out to the " "internet to get information)" -msgstr "" +msgstr "设置网络访问的默认超时限制 (例如在从互联网获取信息时的超时)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:427 msgid " seconds" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:422 -msgid "Choose &language (requires restart):" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:423 -msgid "Normal" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:424 -msgid "High" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:425 -msgid "Low" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:426 -msgid "Job &priority:" -msgstr "" +msgstr " 秒" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:428 -msgid "Add a directory to the frequently used directories list" -msgstr "" +msgid "Choose &language (requires restart):" +msgstr "选择界面语言, 需重启(&l):" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:429 +msgid "Normal" +msgstr "普通" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:430 -msgid "Remove a directory from the frequently used directories list" -msgstr "" +msgid "High" +msgstr "高" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:431 +msgid "Low" +msgstr "低" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:432 -msgid "Use &Roman numerals for series number" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:433 -msgid "&Number of covers to show in browse mode (after restart):" -msgstr "" +msgid "Job &priority:" +msgstr "进程优先级(&p):" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:434 -msgid "Toolbar" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:435 -msgid "Large" -msgstr "" +msgid "Add a directory to the frequently used directories list" +msgstr "将目录添加到常用目录列表中" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:436 -msgid "Medium" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:437 -msgid "Small" -msgstr "" +msgid "Remove a directory from the frequently used directories list" +msgstr "将目录从常用目录列表中移除" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:438 -msgid "&Button size in toolbar" -msgstr "" +msgid "Use &Roman numerals for series number" +msgstr "使用罗马数字作为序列数(&R)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:439 -msgid "Show &text in toolbar buttons" -msgstr "" +msgid "Enable system &tray icon (needs restart)" +msgstr "显示系统托盘图标, 需重启生效(&t)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:440 -msgid "Select visible &columns in library view" +msgid "Show ¬ifications in system tray" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:441 +msgid "Show cover &browser in a separate window (needs restart)" +msgstr "在单独的窗口显示封面浏览界面, 需重启生效(&b)" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:442 +msgid "Automatically send downloaded &news to ebook reader" +msgstr "自动将下载的新闻传输到电子书阅读器上(&n)" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:443 -msgid "Use internal &viewer for the following formats:" -msgstr "" +msgid "&Delete news from library when it is sent to reader" +msgstr "传输到电子书后将新闻从书库中删除(&D)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:444 -msgid "Enable system &tray icon (needs restart)" +msgid "&Number of covers to show in browse mode (needs restart):" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:445 -msgid "Automatically send downloaded &news to ebook reader" -msgstr "" +msgid "Toolbar" +msgstr "工具栏" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:446 -msgid "&Delete news from library when it is sent to reader" -msgstr "" +msgid "Large" +msgstr "大" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:447 -msgid "Show cover &browser in a separate window (needs restart)" -msgstr "" +msgid "Medium" +msgstr "中" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:448 -msgid "Free unused diskspace from the database" -msgstr "" +msgid "Small" +msgstr "小" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:449 -msgid "&Compact database" -msgstr "" +msgid "&Button size in toolbar" +msgstr "工具栏按钮大小(&B)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:450 -msgid "&Metadata from file name" -msgstr "" +msgid "Show &text in toolbar buttons" +msgstr "在工具栏显示按钮文字(&t)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:451 +msgid "Select visible &columns in library view" +msgstr "选择在书库界面中显示的新系列(&c)" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:454 +msgid "Use internal &viewer for:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:455 +msgid "Free unused diskspace from the database" +msgstr "从数据库中释放不用的磁盘空间" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:456 +msgid "&Compact database" +msgstr "压缩数据库(&C)" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:457 +msgid "&Metadata from file name" +msgstr "使用文件名作为metadata(&M)" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:458 msgid "" "calibre contains a network server that allows you to access your book " "collection using a browser from anywhere in the world. Any changes to the " "settings will only take effect after a server restart." -msgstr "" +msgstr "calibre带有一个网络服务器程序, 您可以由此使用浏览器访问你的书籍库. 对服务器程序配置的修改需要重启服务器程序生效." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:452 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:459 msgid "Server &port:" -msgstr "" +msgstr "服务器端口(&p):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:453 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:460 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:146 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:174 msgid "&Username:" -msgstr "" +msgstr "用户名(&U):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:454 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:461 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:147 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:175 msgid "&Password:" -msgstr "" +msgstr "密码(&P):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:455 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:462 msgid "" "If you leave the password blank, anyone will be able to access your book " "collection using the web interface." -msgstr "" +msgstr "如果您使用空密码将导致其他人可以从web界面访问您的书籍库." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:456 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:463 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:148 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:176 msgid "&Show password" -msgstr "" +msgstr "显示密码(&S)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:457 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:464 msgid "" "The maximum size (widthxheight) for displayed covers. Larger covers are " "resized. " -msgstr "" +msgstr "显示书籍封面的最大尺寸(宽度x高度). 过大的封面将会被相应缩小. " -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:458 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:465 msgid "Max. &cover size:" -msgstr "" +msgstr "最大封面大小(&c):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:459 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:466 msgid "&Start Server" -msgstr "" +msgstr "启动服务器(&S)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:460 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:467 msgid "St&op Server" -msgstr "" +msgstr "停止服务器(&o)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:461 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:468 msgid "&Test Server" -msgstr "" +msgstr "测试服务器(&T)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:462 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:469 msgid "Run server &automatically on startup" -msgstr "" +msgstr "在系统启动时自动启动服务器(&a)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:463 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:470 msgid "View &server logs" -msgstr "" +msgstr "察看服务器日志(&s)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:464 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:471 msgid "" "If you want to use the content server to access your ebook collection on " "your iphone with Stanza, you will need to add the URL " @@ -2236,59 +2421,61 @@ msgid "" "iphone. Here myhostname should be the fully qualified hostname or the IP " "address of this computer." msgstr "" +"如果您想从iPhone手机上通过Stanza访问服务器, 您需要将地址 http://myhostname:8080/stanza " +"作为一个新的分类目录添加到iPhone手机上的Stanza阅读程序中. 其中myhostname可以是您的计算机的主机名或IP地址." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:465 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:472 msgid "" "Here you can customize the behavior of Calibre by controlling what plugins " "it uses." -msgstr "" +msgstr "从可以通过配置插件的启用与否来调整Calibre的功能特性." -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:466 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:473 msgid "Enable/&Disable plugin" -msgstr "" +msgstr "启用/禁用插件(&D)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:467 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:474 msgid "&Customize plugin" -msgstr "" +msgstr "设置插件&C)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:468 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:475 msgid "&Remove plugin" -msgstr "" +msgstr "移除插件(&R)" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:469 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:476 msgid "Add new plugin" -msgstr "" +msgstr "添加插件" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:470 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:477 msgid "Plugin &file:" -msgstr "" +msgstr "插件文件名(&f):" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:472 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:479 msgid "&Add" -msgstr "" +msgstr "添加(&A)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:48 msgid "Are you sure?" -msgstr "" +msgstr "您确定吗?" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:50 msgid "&Show this warning again" -msgstr "" +msgstr "重复显示警告(&S)" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/conversion_error_ui.py:41 msgid "ERROR" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:50 -msgid "Bulk convert to EPUB" -msgstr "" +msgstr "错误" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:52 -msgid "Convert %s to EPUB" +msgid "Bulk convert to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:54 +msgid "Convert %s to " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:68 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:95 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:55 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:296 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:143 @@ -2296,304 +2483,315 @@ msgstr "" msgid "Metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:70 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:57 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:297 msgid "Look & Feel" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:61 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:72 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:59 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:298 msgid "Page Setup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:63 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:98 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:61 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:299 msgid "Chapter Detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:95 msgid "" "Specify metadata such as title and author for the book.\n" "\n" -"Metadata will be updated in the database as well as the generated EPUB file." +"Metadata will be updated in the database as well as the generated %s file." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 msgid "" -"Adjust the look of the generated EPUB file by specifying things like font " -"sizes." +"Adjust the look of the generated ebook by specifying things like font sizes." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 msgid "Specify the page layout settings like margins." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:98 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:299 msgid "Fine tune the detection of chapter and section headings." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:93 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:104 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:167 msgid "Choose cover for " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:100 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:111 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:59 msgid "Cannot read" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:101 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:175 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:60 msgid "You do not have permission to read the file: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:109 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:120 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:68 msgid "Error reading file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:184 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:69 msgid "<p>There was an error reading from file: <br /><b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:127 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:190 msgid " is not a valid picture" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:227 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1039 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1053 msgid "Cannot convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:239 msgid "This book has no available formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:244 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 msgid "No available formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:245 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:94 msgid "Cannot convert %s as this book has no supported formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:238 -msgid "Choose the format to convert to EPUB" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:249 +msgid "Choose the format to convert to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:260 msgid "Invalid XPath expression" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:250 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:261 msgid "The expression %s is invalid. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:410 msgid "Convert to EPUB" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:494 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:341 msgid "Book Cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -msgid "Use cover from &source file" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:412 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:495 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:342 msgid "Change &cover image:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:413 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:496 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:343 msgid "Browse for an image to use as the cover of this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:415 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:498 +msgid "Use cover from &source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:416 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:499 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 msgid "&Title: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:379 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:417 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:500 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 msgid "Change the title of this book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:380 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:501 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 msgid "&Author(s): " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:381 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:502 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 msgid "" "Change the author(s) of this book. Multiple authors should be separated by " "an &. If the author name contains an &, use && to represent it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:382 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 msgid "Author So&rt:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:383 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 msgid "" "Change the author(s) of this book. Multiple authors should be separated by a " "comma" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:384 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:422 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:136 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:324 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:318 msgid "&Publisher: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:385 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:423 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:137 msgid "Change the publisher of this book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:386 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:325 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:319 msgid "Ta&gs: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:387 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:139 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:326 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:320 msgid "" "Tags categorize the book. This is particularly useful while searching. " "<br><br>They can be any words or phrases, separated by commas." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:388 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:426 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:144 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:323 msgid "&Series:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:389 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:390 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:427 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:428 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:145 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:146 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:330 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:331 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:324 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:325 msgid "List of known series. You can add new series." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:391 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:392 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:334 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:429 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:430 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:328 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:329 msgid "Series index." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:393 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:431 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:330 msgid "Book " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:395 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:433 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 msgid "Source en&coding:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:396 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:434 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 msgid "Base &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:397 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:403 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:405 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:407 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:442 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:444 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:448 msgid " pt" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:398 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:436 msgid "Remove &spacing between paragraphs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:437 msgid "Preserve &tag structure when splitting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:400 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:438 +msgid "&Rescale images" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:439 msgid "Override &CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:402 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:441 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 msgid "&Left Margin:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 msgid "&Right Margin:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:406 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:563 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:445 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 msgid "&Top Margin:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:408 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:565 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:447 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 msgid "&Bottom Margin:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:410 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:449 msgid "Do not &split on page breaks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:450 +msgid "&Source profile:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:451 +msgid "&Destination profile:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:452 msgid "Automatic &chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:412 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:453 msgid "&XPath:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:413 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:454 msgid "" "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" " "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" @@ -2611,38 +2809,42 @@ msgid "" "tutorial</span></a></p></body></html>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:418 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:459 msgid "Chapter &mark:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:460 msgid "Automatic &Table of Contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:420 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:461 msgid "Number of &links to add to Table of Contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:421 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:462 msgid "Do not add &detected chapters to the Table of Contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:422 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:463 msgid "Chapter &threshold" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:423 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:464 msgid "&Force use of auto-generated Table of Contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:465 msgid "Level &1 TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:466 msgid "Level &2 TOC" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:467 +msgid "&Title for generated TOC" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:38 msgid "Author Sort" msgstr "" @@ -2703,7 +2905,7 @@ msgid "" "Select the book that most closely matches your copy from the list below" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/job_view_ui.py:33 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/job_view_ui.py:32 msgid "Details of job" msgstr "" @@ -2732,7 +2934,7 @@ msgid "Convert %s to LRF" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:109 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:360 msgid "Set conversion defaults" msgstr "" @@ -2782,158 +2984,150 @@ msgstr "" msgid "Bulk convert ebooks to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:492 msgid "Convert to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 -msgid "Options" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:544 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:546 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 msgid " pts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 msgid "Embedded Fonts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 msgid "&Serif:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:540 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 msgid "S&ans-serif:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 msgid "&Monospace:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 msgid "Minimum &indent:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 msgid "&Word spacing:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 msgid "Enable auto &rotation of images" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 msgid "Insert &blank lines between paragraphs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 msgid "Ignore &tables" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:550 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 msgid "Ignore &colors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 msgid "&Preprocess:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 msgid "Header" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 msgid "&Show header" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 msgid "&Header format:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:562 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:564 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:566 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:535 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:540 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:542 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:544 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:546 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:107 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:109 msgid " px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:556 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 msgid "Header &separation:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 msgid "Override<br>CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:567 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:568 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 msgid "&Multiplier for text size in rendered tables:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:569 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 msgid "Title based detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:570 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:550 msgid "&Disable chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:571 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 msgid "&Regular expression:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:572 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 msgid "Add &chapters to table of contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:573 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 msgid "Don't add &links to the table of contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:574 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:554 msgid "Tag based detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:575 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 msgid "&Page break before tag:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:576 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:556 msgid "&Force page break before tag:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:577 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 msgid "Force page break before &attribute:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:578 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 msgid "Detect chapter &at tag:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:579 -msgid "Help on item" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:580 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "" "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" " "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style " "type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" -"</style></head><body style=\" font-family:'Sans Serif'; font-size:10pt; font-" -"weight:400; font-style:normal;\">\n" +"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; " +"font-weight:400; font-style:normal;\">\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; " -"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-" -"family:'DejaVu Sans';\"></p></body></html>" +"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-" +"indent:0px;\"></p></body></html>" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:126 @@ -2941,36 +3135,36 @@ msgid "Edit Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:127 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:304 msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:130 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:310 msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:131 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:132 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:320 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:133 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:134 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:321 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:322 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 msgid "Rating of this book. 0-5 stars" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:135 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:323 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 msgid " stars" msgstr "" @@ -2980,8 +3174,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:140 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:141 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:327 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:328 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:321 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:322 msgid "Open Tag Editor" msgstr "" @@ -3022,84 +3216,84 @@ msgstr "" msgid "The cover in the %s format is invalid" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:321 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:319 msgid "" "<p>Enter your username and password for <b>LibraryThing.com</b>. <br/>If you " "do not have one, you can <a href='http://www.librarything.com'>register</a> " "for free!.</p>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:349 msgid "<b>Could not fetch cover.</b><br/>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:349 msgid "Could not fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:355 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:355 msgid "You must specify the ISBN identifier for this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:318 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:312 msgid "" "Automatically create the author sort entry based on the current author entry" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:326 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:331 msgid "IS&BN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:333 msgid "Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:334 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:335 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:337 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:339 msgid "Set the cover for the book from the selected format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:345 msgid "Reset cover to default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:347 msgid "Fetch cover image from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:354 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:348 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:349 msgid "Change password" msgstr "" @@ -3107,112 +3301,157 @@ msgstr "" msgid "Password needed" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress.py:42 +msgid "Aborting..." +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:39 msgid "You" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:184 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:218 msgid "Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:261 msgid "%d recipes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:264 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +msgid "Monday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +msgid "Tuesday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +msgid "Wednesday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +msgid "day" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +msgid "Friday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +msgid "Saturday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +msgid "Sunday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +msgid "Thursday" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:292 msgid "Must set account information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:264 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:292 msgid "This recipe requires a username and password" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:277 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:317 msgid "Created by: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:297 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:355 msgid "Last downloaded: %s days ago" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:299 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:357 msgid "Last downloaded: never" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:326 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:384 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:161 msgid "Schedule news download" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:387 msgid "Add a custom news source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:336 -#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:42 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:752 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:756 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1063 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:394 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:772 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:776 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1083 msgid "News" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221 msgid "Recipes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:163 msgid "Schedule for download" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:139 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:164 msgid "title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:140 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:165 msgid "description" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:141 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:166 msgid "author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:142 -msgid "&Schedule for download every:" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:167 +msgid "&Schedule for download:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:143 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:170 +msgid "Every " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:169 +msgid "at" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:171 msgid "" "Interval at which to download this recipe. A value of zero means that the " "recipe will be downloaded every hour." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:144 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:152 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:180 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:263 msgid " days" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:145 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:173 msgid "&Account" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:149 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:177 msgid "For the scheduling to work, you must leave calibre running." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:178 msgid "&Download now" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:151 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:179 msgid "" "Delete downloaded news older than the specified number of days. Set to zero " "to disable." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:181 msgid "Delete downloaded news older than " msgstr "" @@ -3313,118 +3552,118 @@ msgstr "" msgid "Add tag to available tags and apply it to current book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:62 msgid "No recipe selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:68 msgid "The attached file: %s is a recipe to download %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:70 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:69 msgid "Recipe for " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:86 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:97 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:255 msgid "Switch to Advanced mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:92 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:100 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:99 msgid "Switch to Basic mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:109 msgid "Feed must have a title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:110 msgid "The feed must have a title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:114 msgid "Feed must have a URL" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:115 msgid "The feed %s must have a URL" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:120 msgid "Already exists" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:121 msgid "This feed has already been added to the recipe" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228 +msgid "Invalid input" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229 -msgid "Invalid input" +msgid "<p>Could not create recipe. Error:<br>%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230 -msgid "<p>Could not create recipe. Error:<br>%s" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234 +msgid "Replace recipe?" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235 -msgid "Replace recipe?" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236 msgid "A custom recipe named %s already exists. Do you want to replace it?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:202 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:201 msgid "Pick recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:202 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:201 msgid "Pick the recipe to customize" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221 msgid "Choose a recipe file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:214 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:248 msgid "Add custom news source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:215 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:249 msgid "Available user recipes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:216 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:250 msgid "Add/Update &recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:251 msgid "&Remove recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:218 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:252 msgid "&Share recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:253 msgid "Customize &builtin recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:220 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:254 msgid "&Load recipe from file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:256 msgid "" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style " "type=\"text/css\">\n" @@ -3438,58 +3677,58 @@ msgid "" "process.</p></body></html>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:260 msgid "Recipe &title:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:261 msgid "&Oldest article:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:262 msgid "The oldest article to download" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:264 msgid "&Max. number of articles per feed:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:265 msgid "Maximum number of articles to download per feed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:266 msgid "Feeds in recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:268 msgid "Remove feed from recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:237 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:274 msgid "Add feed to recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:272 msgid "&Feed title:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:239 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:273 msgid "Feed &URL:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:275 msgid "&Add feed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:242 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:276 msgid "" "For help with writing advanced news recipes, please visit <a " "href=\"http://calibre.kovidgoyal.net/user_manual/news.html\">User Recipes</a>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:243 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:277 msgid "Recipe source code (python)" msgstr "" @@ -3636,12 +3875,12 @@ msgid "Job has already run" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library.py:105 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:933 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:971 msgid "Size (MB)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library.py:106 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:934 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:972 msgid "Date" msgstr "" @@ -3649,35 +3888,35 @@ msgstr "" msgid "Rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:292 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:298 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:308 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:319 msgid "None" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:309 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:325 msgid "Book <font face=\"serif\">%s</font> of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:701 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:739 msgid "Not allowed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:702 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:740 msgid "" "Dropping onto a device is not supported. First add the book to the calibre " "library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:865 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:903 msgid "Format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:870 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:908 msgid "Timestamp" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:968 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:1006 msgid "Search (For Advanced Search click the button to the left)" msgstr "" @@ -3753,156 +3992,148 @@ msgstr "" msgid "Configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:90 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:101 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:102 msgid "&Restore" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:102 -msgid "&Donate" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/main.py:103 -msgid "&Quit" +msgid "&Donate to support calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:106 msgid "&Restart" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:149 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:142 msgid "" "<p>For help visit <a " "href=\"http://%s.kovidgoyal.net/user_manual\">%s.kovidgoyal.net</a><br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:143 msgid "<b>%s</b>: %s by <b>Kovid Goyal %%(version)s</b><br>%%(device)s</p>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:168 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:163 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:169 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:164 msgid "Send to storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:170 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:164 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:166 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:186 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:188 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:191 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:184 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:192 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:185 msgid "" "Add books from directories, including sub-directories (One book per " "directory, assumes every ebook file is the same book in a different format)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:186 msgid "" "Add books from directories, including sub directories (Multiple books per " "directory, assumes every ebook file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:208 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:201 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:356 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:209 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:202 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:210 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1243 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:203 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1258 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:213 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:206 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:362 msgid "View" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:214 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:207 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:224 msgid "Convert individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:232 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:225 msgid "Bulk convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:227 msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:228 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:250 msgid "Similar books..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:298 msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:304 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1398 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:300 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1391 msgid "Choose a location for your ebook library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:315 -msgid "Migrating database" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:428 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:424 msgid "Browse by covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:513 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:514 msgid " detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:540 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:551 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:547 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:548 msgid "" "\n" " <p>The database of books on the reader is corrupted. Try the " @@ -3918,455 +4149,467 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:601 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:689 -msgid "Stop" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:604 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:597 msgid "Adding books recursively..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:608 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:602 msgid "Added " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:608 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:602 msgid "Searching..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:620 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:726 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:612 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:716 msgid "" "<p>Books with the same title as the following already exist in the database. " "Add them anyway?<ul>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:623 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:729 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:615 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:719 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:656 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:680 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:649 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:673 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:657 msgid "Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:665 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:658 msgid "EPUB Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:666 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:659 msgid "LRF Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:667 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:660 msgid "HTML Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:668 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:661 msgid "LIT Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:669 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:662 msgid "MOBI Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:670 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:663 msgid "Text books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:671 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:664 msgid "PDF Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:672 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:665 msgid "Comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:673 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:666 msgid "Archives" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:689 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:692 -msgid "Reading metadata..." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:690 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 msgid "Adding books..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:716 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:682 +msgid "Reading metadata..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:707 msgid "Read metadata from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:719 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:710 msgid "Adding books to database..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:763 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:751 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:764 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 msgid "" "<p>Cannot upload books to device there is no more free space available " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:796 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:784 msgid "" "The selected books will be <b>permanently deleted</b> and the files removed " "from your computer. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:805 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:793 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:836 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:861 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:824 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:849 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:836 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:861 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:980 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1039 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:824 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:849 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:974 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1053 msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:908 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:900 msgid "Sending news to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:960 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:953 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:963 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:956 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:964 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:957 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:<br><ul>%s</ul>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:980 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:974 msgid "Cannot save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:984 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:978 +msgid "Saving to disk..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:983 +msgid "Saved" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:989 msgid "Choose destination directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:991 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1003 msgid "" "<p>Could not save the following books to disk, because the %s format is not " "available for them:<ul>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:995 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1007 msgid "Could not save some ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1015 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1029 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1029 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1043 msgid " fetched." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1167 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1179 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1164 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1182 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1194 msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1149 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1179 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1195 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1164 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1194 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1210 msgid "Cannot view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1155 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1200 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1170 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1215 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1167 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1182 msgid "Cannot open folder" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1196 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1211 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1234 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1249 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1234 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1249 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1252 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1267 msgid "Copying database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1254 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1269 msgid "Copying library to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1264 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1279 msgid "Invalid database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1265 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1280 msgid "" "<p>An invalid database already exists at %s, delete it before trying to move " "the existing database.<br>Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1271 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1286 msgid "Could not move database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1291 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1306 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1292 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1307 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1335 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1350 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1336 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1351 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1349 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:1364 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1368 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1379 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1383 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1350 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1365 msgid "" "<p>Could not convert: %s<p>It is a <a href=\"%s\">DRM</a>ed book. You must " "first remove the DRM using 3rd party tools." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1384 -msgid "Database does not exist" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1385 -msgid "" -"The directory in which the database should be: %s no longer exists. Please " -"choose a new database location." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1387 -msgid "Choose new location for database" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1445 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1435 msgid "" "is the result of the efforts of many volunteers from all over the world. If " "you find it useful, please consider donating to support its development." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1467 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1457 msgid "There are active jobs. Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1469 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1459 msgid "" " is communicating with the device!<br>\n" " 'Quitting may cause corruption on the device.<br>\n" " 'Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1473 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1463 msgid "WARNING: Active jobs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1505 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1497 msgid "" "will keep running in the system tray. To close it, choose <b>Quit</b> in the " "context menu of the system tray." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1522 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1514 msgid "" "<span style=\"color:red; font-weight:bold\">Latest version: <a " "href=\"%s\">%s</a></span>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1527 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1519 msgid "" "%s has been updated to version %s. See the <a " "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. " "Visit the download page?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1527 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1519 msgid "Update available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1542 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1534 msgid "Use the library located at the specified path." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1544 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1536 +msgid "Start minimized to system tray." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1538 msgid "Log debugging information to console" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:319 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:328 msgid "calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:320 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:330 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:331 +msgid "Donate to support the development of calibre" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:333 msgid "Output:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:321 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:334 +msgid "" +"Set the output format that is used when converting ebooks and downloading " +"news" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:335 msgid "Advanced search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:323 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:337 msgid "Alt+S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:324 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:338 msgid "&Search:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:325 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:339 msgid "" "Search the list of books by title or author<br><br>Words separated by spaces " "are ANDed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:326 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:340 msgid "" "Search the list of books by title, author, publisher, tags and " "comments<br><br>Words separated by spaces are ANDed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:327 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:341 msgid "Reset Quick Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:331 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:345 msgid "Match any" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:346 msgid "Match all" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:333 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:347 msgid "Sort by &popularity" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:334 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:348 msgid "Add books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:349 msgid "A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:336 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:351 msgid "Remove books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:352 msgid "Del" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:353 msgid "Edit meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:354 msgid "E" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:355 msgid "Send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:357 msgid "S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:358 msgid "Fetch news" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:359 msgid "F" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:360 msgid "Convert E-books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:361 msgid "C" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:363 msgid "V" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:350 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:364 msgid "Open containing folder" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:351 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:365 msgid "Show book details" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:366 msgid "Books by same author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:367 msgid "Books in this series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:354 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:368 msgid "Books by this publisher" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:355 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:369 msgid "Books with the same tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:17 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:18 msgid "" "Redirect console output to a dialog window (both stdout and stderr). Useful " "on windows where GUI apps do not have a output streams." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:53 +msgid "&Preferences" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:54 +msgid "&Quit" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:80 msgid "ERROR: Unhandled exception" msgstr "" @@ -4378,72 +4621,72 @@ msgstr "" msgid "Click to see list of active jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:154 msgid "Click to browse books by their covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:154 msgid "Click to turn off Cover Browsing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159 msgid "" "<p>Browsing books by their covers is disabled.<br>Import of pictureflow " "module failed:<br>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/status.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/status.py:167 msgid "Click to browse books by tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 msgid "Authors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 msgid "Publishers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:48 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:117 msgid "Convert book: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:80 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:151 msgid "Convert comic: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:166 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:267 msgid "Starting Bulk conversion of %d books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:203 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:231 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:300 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:328 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:335 msgid "Convert book %d of %d (%s)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:240 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:344 msgid "" "<p>Could not convert %d of %d books, because no suitable source format was " "found.<ul>%s</ul>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:241 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:338 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:248 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:345 msgid "Could not convert some books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:366 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:381 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:372 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:387 msgid "Fetch news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:378 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:384 msgid "You must set a username and password for %s" msgstr "" @@ -4534,11 +4777,6 @@ msgstr "" msgid "The standard font type" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:47 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:160 -msgid "Table of Contents" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:166 msgid "Go to..." msgstr "" @@ -4732,7 +4970,7 @@ msgid "Username for access. By default, it is: %default" msgstr "" #: /home/kovid/work/calibre/src/calibre/library/__init__.py:32 -msgid "The maximum size for displayed covers" +msgid "The maximum size for displayed covers. Default is %default." msgstr "" #: /home/kovid/work/calibre/src/calibre/library/cli.py:107 @@ -4962,20 +5200,20 @@ msgid "" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1159 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1179 msgid "<p>Copying books to %s<br><center>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1172 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1281 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1192 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1301 msgid "Copying <b>%s</b>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1252 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1272 msgid "<p>Migrating old database to ebook library in %s<br><center>" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1298 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1318 msgid "Compacting database" msgstr "" @@ -4990,11 +5228,11 @@ msgid "" "Start the calibre content server." msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:367 +#: /home/kovid/work/calibre/src/calibre/parallel.py:387 msgid "Could not launch worker process." msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:793 +#: /home/kovid/work/calibre/src/calibre/parallel.py:813 msgid "Job stopped by user" msgstr "" @@ -5081,28 +5319,28 @@ msgid "Customize the download engine" msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:20 -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:442 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:455 msgid "" "Timeout in seconds to wait for a response from the server. Default: %default " "s" msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:22 -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:450 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:463 msgid "" "Minimum interval in seconds between consecutive fetches. Default is %default " "s" msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:24 -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:452 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:465 msgid "" "The character encoding for the websites you are trying to download. The " "default is to try and guess the encoding." msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:26 -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:454 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:467 msgid "" "Only links that match this regular expression will be followed. This option " "can be specified multiple times, in which case as long as a link matches any " @@ -5110,7 +5348,7 @@ msgid "" msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:28 -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:456 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:469 msgid "" "Any link that matches this regular expression will be ignored. This option " "can be specified multiple times, in which case as long as any regexp matches " @@ -5120,12 +5358,12 @@ msgid "" msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:30 -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:458 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:471 msgid "Do not download CSS stylesheets." msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:33 -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:88 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:90 msgid "" "Specify a list of feeds to download. For example: \n" "\"['http://feeds.newsweek.com/newsweek/TopNews', " @@ -5135,58 +5373,58 @@ msgid "" msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37 -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:92 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:94 msgid "Be more verbose while processing." msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:39 -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:94 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 msgid "" "The title for this recipe. Used as the title for any ebooks created from the " "downloaded feeds." msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:41 -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:95 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:97 msgid "Username for sites that require a login to access content." msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:43 -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:96 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:98 msgid "Password for sites that require a login to access content." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:49 -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:99 -msgid "" -"Number of levels of links to follow on webpages that are linked to from " -"feeds. Defaul %default" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:51 #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:101 msgid "" +"Number of levels of links to follow on webpages that are linked to from " +"feeds. Defaul %default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:53 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:103 +msgid "" "The directory in which to store the downloaded feeds. Defaults to the " "current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:53 -msgid "Don't show the progress bar" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:55 -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:105 -msgid "Very verbose output, useful for debugging." +msgid "Don't show the progress bar" msgstr "" #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57 #: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:107 +msgid "Very verbose output, useful for debugging." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:59 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:109 msgid "" "Useful for recipe development. Forces max_articles_per_feed to 2 and " "downloads at most 2 feeds." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:61 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:63 msgid "" "%%prog [options] ARG\n" "\n" @@ -5207,17 +5445,17 @@ msgid "" "%s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:85 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:87 msgid "" "Options to control web2disk (used to fetch websites linked from feeds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:103 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:105 msgid "Dont show the progress bar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:118 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:675 +#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:120 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:681 msgid "Fetching feeds..." msgstr "" @@ -5225,105 +5463,114 @@ msgstr "" msgid "Unknown News Source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:556 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:560 msgid "Download finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:558 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:562 msgid "Failed to download the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:560 -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:566 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:564 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:570 msgid " from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:564 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:568 msgid "Failed to download parts of the following articles:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:568 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:572 msgid "\tFailed links:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:654 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:660 msgid "Could not fetch article. Run with --debug to see the reason" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:679 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:685 msgid "Got feeds from index page" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:685 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:691 msgid "Trying to download cover..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:738 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:744 msgid "Starting download [%d thread(s)]..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:754 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:760 msgid "Feeds downloaded to %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:764 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:770 msgid "Could not download cover: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:771 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:777 msgid "Downloading cover from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:900 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:910 msgid "Untitled Article" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:955 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:965 msgid "" "\n" "Downloaded article %s from %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:961 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:971 msgid "Article downloaded: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:967 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:977 msgid "Failed to download article: %s from %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:972 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:982 msgid "Article download failed: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:987 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:997 msgid "Fetching feed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:436 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:449 msgid "" "%prog URL\n" "\n" "Where URL is for example http://google.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:439 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:452 msgid "Base directory into which URL is saved. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:445 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:458 msgid "" "Maximum number of levels to recurse i.e. depth of links to follow. Default " "%default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:448 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:461 msgid "" "The maximum number of files to download. This only applies to files from <a " "href> tags. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:459 +#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:472 msgid "Show detailed output information. Useful for debugging" msgstr "" + +#~ msgid "Set metadata in EPUB files" +#~ msgstr "设置EPUB文件的metadata" + +#~ msgid "Set metadata in LRF files" +#~ msgstr "设置LRF文件的metadata" + +#~ msgid "Set metadata in RTF files" +#~ msgstr "设置RTF文件的metadata" diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index bc7b2e62bf..660b98fd44 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -47,6 +47,9 @@ class BasicNewsRecipe(object, LoggingInterface): #: The author of this recipe __author__ = __appname__ + #: The language that the news is in + language = _('Unknown') + #: Maximum number of articles to download from each feed. This is primarily #: useful for feeds that don't have article dates. For most feeds, you should #: use :attr:`BasicNewsRecipe.oldest_article` diff --git a/src/calibre/web/feeds/recipes/__init__.py b/src/calibre/web/feeds/recipes/__init__.py index d087004dbe..0a05d9b270 100644 --- a/src/calibre/web/feeds/recipes/__init__.py +++ b/src/calibre/web/feeds/recipes/__init__.py @@ -24,7 +24,9 @@ recipe_modules = ['recipe_' + r for r in ( 'joelonsoftware', 'telepolis', 'common_dreams', 'nin', 'tomshardware_de', 'pagina12', 'infobae', 'ambito', 'elargentino', 'sueddeutsche', 'the_age', 'laprensa', 'amspec', 'freakonomics', 'criticadigital', 'elcronista', - 'shacknews', 'teleread', + 'shacknews', 'teleread', 'granma', 'juventudrebelde', 'juventudrebelde_english', + 'la_tercera', 'el_mercurio_chile', 'la_cuarta', 'lanacion_chile', 'la_segunda', + 'jb_online', 'estadao', 'o_globo', 'vijesti', 'elmundo', 'the_oz', 'exiled', )] import re, imp, inspect, time, os diff --git a/src/calibre/web/feeds/recipes/recipe_ambito.py b/src/calibre/web/feeds/recipes/recipe_ambito.py index 56528c27c0..17d33a1cde 100644 --- a/src/calibre/web/feeds/recipes/recipe_ambito.py +++ b/src/calibre/web/feeds/recipes/recipe_ambito.py @@ -18,6 +18,7 @@ class Ambito(BasicNewsRecipe): no_stylesheets = True use_embedded_content = False encoding = 'iso--8859-1' + language = _('Spanish') cover_url = 'http://www.ambito.com/img/logo_.jpg' html2lrf_options = [ diff --git a/src/calibre/web/feeds/recipes/recipe_amspec.py b/src/calibre/web/feeds/recipes/recipe_amspec.py index b01fadee77..0e5358dd26 100644 --- a/src/calibre/web/feeds/recipes/recipe_amspec.py +++ b/src/calibre/web/feeds/recipes/recipe_amspec.py @@ -9,27 +9,28 @@ spectator.org from calibre.web.feeds.news import BasicNewsRecipe class TheAmericanSpectator(BasicNewsRecipe): - title = 'The American Spectator' - __author__ = 'Darko Miletic' - description = 'news from USA' - oldest_article = 7 - max_articles_per_feed = 100 - no_stylesheets = True - use_embedded_content = False - INDEX = 'http://spectator.org' + title = 'The American Spectator' + __author__ = 'Darko Miletic' + language = _('English') + description = 'News from USA' + oldest_article = 7 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + INDEX = 'http://spectator.org' - html2lrf_options = [ + html2lrf_options = [ '--comment' , description , '--category' , 'news, politics, USA' , '--publisher' , title ] - keep_only_tags = [ + keep_only_tags = [ dict(name='div', attrs={'class':'post inner'}) ,dict(name='div', attrs={'class':'author-bio'}) ] - remove_tags = [ + remove_tags = [ dict(name='object') ,dict(name='div', attrs={'class':'col3' }) ,dict(name='div', attrs={'class':'post-options' }) @@ -37,17 +38,17 @@ class TheAmericanSpectator(BasicNewsRecipe): ,dict(name='div', attrs={'class':'social' }) ] - feeds = [ (u'Articles', u'http://feedproxy.google.com/amspecarticles')] + feeds = [ (u'Articles', u'http://feedproxy.google.com/amspecarticles')] - def get_cover_url(self): - cover_url = None - soup = self.index_to_soup(self.INDEX) - link_item = soup.find('a',attrs={'class':'cover'}) - if link_item: - soup2 = self.index_to_soup(link_item['href']) - link_item2 = soup2.find('div',attrs={'class':'post inner issues'}) - cover_url = self.INDEX + link_item2.img['src'] - return cover_url + def get_cover_url(self): + cover_url = None + soup = self.index_to_soup(self.INDEX) + link_item = soup.find('a',attrs={'class':'cover'}) + if link_item: + soup2 = self.index_to_soup(link_item['href']) + link_item2 = soup2.find('div',attrs={'class':'post inner issues'}) + cover_url = self.INDEX + link_item2.img['src'] + return cover_url - def print_version(self, url): - return url + '/print' + def print_version(self, url): + return url + '/print' diff --git a/src/calibre/web/feeds/recipes/recipe_ap.py b/src/calibre/web/feeds/recipes/recipe_ap.py index cbd9055b61..6bff0ab0a8 100644 --- a/src/calibre/web/feeds/recipes/recipe_ap.py +++ b/src/calibre/web/feeds/recipes/recipe_ap.py @@ -8,6 +8,7 @@ class AssociatedPress(BasicNewsRecipe): description = 'Global news' __author__ = 'Kovid Goyal' use_embedded_content = False + language = _('English') max_articles_per_feed = 15 html2lrf_options = ['--force-page-break-before-tag="chapter"'] diff --git a/src/calibre/web/feeds/recipes/recipe_ars_technica.py b/src/calibre/web/feeds/recipes/recipe_ars_technica.py index b7c25e497a..1360c6aa47 100644 --- a/src/calibre/web/feeds/recipes/recipe_ars_technica.py +++ b/src/calibre/web/feeds/recipes/recipe_ars_technica.py @@ -13,6 +13,7 @@ class ArsTechnica(BasicNewsRecipe): title = 'Ars Technica' description = 'The art of technology' oldest_article = 7 + language = _('English') no_stylesheets = True __author__ = 'Michael Warner' max_articles_per_feed = 100 diff --git a/src/calibre/web/feeds/recipes/recipe_atlantic.py b/src/calibre/web/feeds/recipes/recipe_atlantic.py index 8978925528..6d4a88dcd5 100644 --- a/src/calibre/web/feeds/recipes/recipe_atlantic.py +++ b/src/calibre/web/feeds/recipes/recipe_atlantic.py @@ -14,7 +14,7 @@ class TheAtlantic(BasicNewsRecipe): __author__ = 'Kovid Goyal' description = 'Current affairs and politics focussed on the US' INDEX = 'http://www.theatlantic.com/doc/current' - + language = _('English') remove_tags_before = dict(name='div', id='storytop') remove_tags = [dict(name='div', id=['seealso', 'storybottom', 'footer', 'ad_banner_top', 'sidebar'])] no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_b92.py b/src/calibre/web/feeds/recipes/recipe_b92.py index 47d264af1c..c20bfab8dc 100644 --- a/src/calibre/web/feeds/recipes/recipe_b92.py +++ b/src/calibre/web/feeds/recipes/recipe_b92.py @@ -6,12 +6,13 @@ __copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>' b92.net ''' -import string,re +import re from calibre.web.feeds.news import BasicNewsRecipe class B92(BasicNewsRecipe): title = u'B92' __author__ = 'Darko Miletic' + language = _('Serbian') description = 'Dnevne vesti iz Srbije i sveta' oldest_article = 7 max_articles_per_feed = 100 diff --git a/src/calibre/web/feeds/recipes/recipe_barrons.py b/src/calibre/web/feeds/recipes/recipe_barrons.py index 44ebdaef21..164be20d3e 100644 --- a/src/calibre/web/feeds/recipes/recipe_barrons.py +++ b/src/calibre/web/feeds/recipes/recipe_barrons.py @@ -15,6 +15,7 @@ class Barrons(BasicNewsRecipe): title = 'Barron\'s' max_articles_per_feed = 50 needs_subscription = True + language = _('English') __author__ = 'Kovid Goyal' description = 'Weekly publication for investors from the publisher of the Wall Street Journal' timefmt = ' [%a, %b %d, %Y]' diff --git a/src/calibre/web/feeds/recipes/recipe_bbc.py b/src/calibre/web/feeds/recipes/recipe_bbc.py index 01aa039cf9..bc893c5ad4 100644 --- a/src/calibre/web/feeds/recipes/recipe_bbc.py +++ b/src/calibre/web/feeds/recipes/recipe_bbc.py @@ -13,6 +13,7 @@ class BBC(BasicNewsRecipe): __author__ = 'Kovid Goyal' description = 'Global news and current affairs from the British Broadcasting Corporation' no_stylesheets = True + language = _('English') remove_tags = [dict(name='div', attrs={'class':'footer'})] extra_css = '.headline {font-size: x-large;} \n .fact { padding-top: 10pt }' diff --git a/src/calibre/web/feeds/recipes/recipe_business_week.py b/src/calibre/web/feeds/recipes/recipe_business_week.py index 794bdf9582..d24e1c0f6a 100644 --- a/src/calibre/web/feeds/recipes/recipe_business_week.py +++ b/src/calibre/web/feeds/recipes/recipe_business_week.py @@ -13,6 +13,7 @@ class BusinessWeek(BasicNewsRecipe): title = 'Business Week' description = 'Business News, Stock Market and Financial Advice' __author__ = 'ChuckEggDotCom' + language = _('English') oldest_article = 7 max_articles_per_feed = 10 diff --git a/src/calibre/web/feeds/recipes/recipe_chr_mon.py b/src/calibre/web/feeds/recipes/recipe_chr_mon.py index b9f94fcd1c..ccf17bc2e0 100644 --- a/src/calibre/web/feeds/recipes/recipe_chr_mon.py +++ b/src/calibre/web/feeds/recipes/recipe_chr_mon.py @@ -8,6 +8,7 @@ class ChristianScienceMonitor(BasicNewsRecipe): description = 'Providing context and clarity on national and international news, peoples and cultures' max_articles_per_feed = 20 __author__ = 'Kovid Goyal' + language = _('English') no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_clarin.py b/src/calibre/web/feeds/recipes/recipe_clarin.py index 322e06dd66..cd72163c88 100644 --- a/src/calibre/web/feeds/recipes/recipe_clarin.py +++ b/src/calibre/web/feeds/recipes/recipe_clarin.py @@ -15,6 +15,7 @@ class Clarin(BasicNewsRecipe): description = 'Noticias de Argentina y mundo' oldest_article = 2 max_articles_per_feed = 100 + language = _('Spanish') use_embedded_content = False no_stylesheets = True cover_url = strftime('http://www.clarin.com/diario/%Y/%m/%d/portada.jpg') diff --git a/src/calibre/web/feeds/recipes/recipe_cnn.py b/src/calibre/web/feeds/recipes/recipe_cnn.py index ac286d29ad..6ce0f87d4e 100644 --- a/src/calibre/web/feeds/recipes/recipe_cnn.py +++ b/src/calibre/web/feeds/recipes/recipe_cnn.py @@ -12,6 +12,7 @@ class CNN(BasicNewsRecipe): description = 'Global news' timefmt = ' [%d %b %Y]' __author__ = 'Kovid Goyal' + language = _('English') no_stylesheets = True use_embedded_content = False oldest_article = 15 diff --git a/src/calibre/web/feeds/recipes/recipe_common_dreams.py b/src/calibre/web/feeds/recipes/recipe_common_dreams.py index 18a4233d69..3f44dfd09d 100644 --- a/src/calibre/web/feeds/recipes/recipe_common_dreams.py +++ b/src/calibre/web/feeds/recipes/recipe_common_dreams.py @@ -5,6 +5,7 @@ class CommonDreams(BasicNewsRecipe): title = u'Common Dreams' description = u'Progressive news and views' __author__ = u'XanthanGum' + language = _('English') oldest_article = 7 max_articles_per_feed = 100 diff --git a/src/calibre/web/feeds/recipes/recipe_criticadigital.py b/src/calibre/web/feeds/recipes/recipe_criticadigital.py index b92a33231c..ed04fd8b55 100644 --- a/src/calibre/web/feeds/recipes/recipe_criticadigital.py +++ b/src/calibre/web/feeds/recipes/recipe_criticadigital.py @@ -14,6 +14,7 @@ class CriticaDigital(BasicNewsRecipe): description = 'Noticias de Argentina' oldest_article = 2 max_articles_per_feed = 100 + language = _('Spanish') no_stylesheets = True use_embedded_content = False encoding = 'cp1252' diff --git a/src/calibre/web/feeds/recipes/recipe_cyberpresse.py b/src/calibre/web/feeds/recipes/recipe_cyberpresse.py index cbd26ff784..ead1589e0f 100644 --- a/src/calibre/web/feeds/recipes/recipe_cyberpresse.py +++ b/src/calibre/web/feeds/recipes/recipe_cyberpresse.py @@ -6,6 +6,7 @@ class Cyberpresse(BasicNewsRecipe): title = u'Cyberpresse' __author__ = 'balok' description = 'Canadian news in French' + language = _('French') oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_daily_telegraph.py b/src/calibre/web/feeds/recipes/recipe_daily_telegraph.py index dfad458276..84a379537e 100644 --- a/src/calibre/web/feeds/recipes/recipe_daily_telegraph.py +++ b/src/calibre/web/feeds/recipes/recipe_daily_telegraph.py @@ -12,6 +12,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class DailyTelegraph(BasicNewsRecipe): title = u'Daily Telegraph' __author__ = u'AprilHare' + language = _('English') description = u'News from down under' oldest_article = 2 max_articles_per_feed = 10 diff --git a/src/calibre/web/feeds/recipes/recipe_de_standaard.py b/src/calibre/web/feeds/recipes/recipe_de_standaard.py index 2681f2acd9..f247c14d5c 100644 --- a/src/calibre/web/feeds/recipes/recipe_de_standaard.py +++ b/src/calibre/web/feeds/recipes/recipe_de_standaard.py @@ -9,6 +9,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class DeStandaard(BasicNewsRecipe): title = u'De Standaard' __author__ = u'Darko Miletic' + language = _('French') description = u'News from Belgium' oldest_article = 7 max_articles_per_feed = 100 diff --git a/src/calibre/web/feeds/recipes/recipe_discover_magazine.py b/src/calibre/web/feeds/recipes/recipe_discover_magazine.py index 0e3753834b..9c4c4259a5 100644 --- a/src/calibre/web/feeds/recipes/recipe_discover_magazine.py +++ b/src/calibre/web/feeds/recipes/recipe_discover_magazine.py @@ -13,7 +13,8 @@ class DiscoverMagazine(BasicNewsRecipe): title = u'Discover Magazine' description = u'Science, Technology and the Future' __author__ = 'Mike Diaz' - oldest_article = 33 + oldest_article = 33 + language = _('English') max_articles_per_feed = 20 feeds = [ (u'Technology', u'http://discovermagazine.com/topics/technology/rss.xml'), diff --git a/src/calibre/web/feeds/recipes/recipe_economist.py b/src/calibre/web/feeds/recipes/recipe_economist.py index 9ed19802b4..3dfaa7257d 100644 --- a/src/calibre/web/feeds/recipes/recipe_economist.py +++ b/src/calibre/web/feeds/recipes/recipe_economist.py @@ -14,6 +14,7 @@ from urllib2 import quote class Economist(BasicNewsRecipe): title = 'The Economist' + language = _('English') __author__ = "Kovid Goyal" description = 'Global news and current affairs from a European perspective' oldest_article = 7.0 diff --git a/src/calibre/web/feeds/recipes/recipe_el_mercurio_chile.py b/src/calibre/web/feeds/recipes/recipe_el_mercurio_chile.py new file mode 100644 index 0000000000..0b7d994b34 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_el_mercurio_chile.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +emol.com +''' +from calibre.web.feeds.news import BasicNewsRecipe + +class ElMercurio(BasicNewsRecipe): + title = 'El Mercurio online' + language = _('Spanish') + __author__ = 'Darko Miletic' + description = 'El sitio de noticias online de Chile' + oldest_article = 2 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1252' + cover_url = 'http://www.emol.com/especiales/logo_emol/logo_emol.gif' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Chile' + , '--publisher' , title + ] + + keep_only_tags = [ + dict(name='div', attrs={'class':'despliegue-txt_750px'}) + ,dict(name='div', attrs={'id':'div_cuerpo_participa'}) + ] + + + remove_tags = [ + dict(name='div', attrs={'class':'contenedor_despliegue-col-left300'}) + ,dict(name='div', attrs={'id':['div_centro_dn_opc','div_cabezera','div_secciones','div_contenidos','div_pie','nav']}) + ] + + feeds = [ + (u'Noticias de ultima hora', u'http://www.emol.com/rss20/rss.asp?canal=0') + ,(u'Nacional', u'http://www.emol.com/rss20/rss.asp?canal=1') + ,(u'Mundo', u'http://www.emol.com/rss20/rss.asp?canal=2') + ,(u'Deportes', u'http://www.emol.com/rss20/rss.asp?canal=4') + ,(u'Magazine', u'http://www.emol.com/rss20/rss.asp?canal=6') + ,(u'Tecnologia', u'http://www.emol.com/rss20/rss.asp?canal=5') + ,(u'La Musica', u'http://www.emol.com/rss20/rss.asp?canal=7') + ] + diff --git a/src/calibre/web/feeds/recipes/recipe_el_pais.py b/src/calibre/web/feeds/recipes/recipe_el_pais.py index f3416ebf6d..a738c517aa 100644 --- a/src/calibre/web/feeds/recipes/recipe_el_pais.py +++ b/src/calibre/web/feeds/recipes/recipe_el_pais.py @@ -11,6 +11,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class ElPais(BasicNewsRecipe): title = u'EL PAIS' + language = _('Spanish') oldest_article = 7 max_articles_per_feed = 100 diff --git a/src/calibre/web/feeds/recipes/recipe_elargentino.py b/src/calibre/web/feeds/recipes/recipe_elargentino.py index 7aee232787..ef79c96baa 100644 --- a/src/calibre/web/feeds/recipes/recipe_elargentino.py +++ b/src/calibre/web/feeds/recipes/recipe_elargentino.py @@ -12,6 +12,7 @@ class ElArgentino(BasicNewsRecipe): title = 'ElArgentino.com' __author__ = 'Darko Miletic' description = 'Informacion Libre las 24 horas' + language = _('Spanish') oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_elcronista.py b/src/calibre/web/feeds/recipes/recipe_elcronista.py index f425f99e7a..c875ba45ce 100644 --- a/src/calibre/web/feeds/recipes/recipe_elcronista.py +++ b/src/calibre/web/feeds/recipes/recipe_elcronista.py @@ -13,6 +13,7 @@ class ElCronista(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Noticias de Argentina' oldest_article = 2 + language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_elmundo.py b/src/calibre/web/feeds/recipes/recipe_elmundo.py new file mode 100644 index 0000000000..9fd6eefb35 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_elmundo.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +elmundo.es +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class ElMundo(BasicNewsRecipe): + title = 'El Mundo' + __author__ = 'Darko Miletic' + description = 'News from Spain' + language = _('Spanish') + oldest_article = 2 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'iso8859_15' + cover_url = 'http://estaticos02.cache.el-mundo.net/papel/imagenes/v2.0/logoverde.gif' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Spain' + , '--publisher' , title + ] + + keep_only_tags = [dict(name='div', attrs={'class':'noticia'})] + + remove_tags = [ + dict(name='div', attrs={'class':['herramientas','publicidad_google','video','herramientasarriba','contenido_noticia_02']}) + ,dict(name='div', attrs={'id':'modulo_multimedia' }) + ,dict(name=['object','script','link', 'a']) + ,dict(name='ul', attrs={'class':'herramientas'}) + ] + + feeds = [ + (u'Portada' , u'http://rss.elmundo.es/rss/descarga.htm?data2=4' ) + ,(u'Television' , u'http://rss.elmundo.es/rss/descarga.htm?data2=76') + ,(u'Espana' , u'http://rss.elmundo.es/rss/descarga.htm?data2=8' ) + ,(u'Internacional' , u'http://rss.elmundo.es/rss/descarga.htm?data2=9' ) + ,(u'Cultura' , u'http://rss.elmundo.es/rss/descarga.htm?data2=6' ) + ,(u'Ciencia/Ecologia', u'http://rss.elmundo.es/rss/descarga.htm?data2=5' ) + ,(u'Comunicacion' , u'http://rss.elmundo.es/rss/descarga.htm?data2=26') + ] diff --git a/src/calibre/web/feeds/recipes/recipe_endgadget.py b/src/calibre/web/feeds/recipes/recipe_endgadget.py index 7593d2578e..bcf9fc13f4 100644 --- a/src/calibre/web/feeds/recipes/recipe_endgadget.py +++ b/src/calibre/web/feeds/recipes/recipe_endgadget.py @@ -12,7 +12,8 @@ from calibre.web.feeds.news import BasicNewsRecipe class Engadget(BasicNewsRecipe): title = u'Engadget' __author__ = 'Darko Miletic' - description = 'Tech news' + description = 'Tech news' + language = _('English') oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_espn.py b/src/calibre/web/feeds/recipes/recipe_espn.py index 34a1bc609a..4951d21f9b 100644 --- a/src/calibre/web/feeds/recipes/recipe_espn.py +++ b/src/calibre/web/feeds/recipes/recipe_espn.py @@ -14,6 +14,7 @@ class ESPN(BasicNewsRecipe): title = 'ESPN' description = 'Sports news' __author__ = 'Kovid Goyal' + language = _('English') needs_subscription = True remove_tags = [dict(name='font', attrs={'class':'footer'}), dict(name='hr', noshade='noshade')] diff --git a/src/calibre/web/feeds/recipes/recipe_estadao.py b/src/calibre/web/feeds/recipes/recipe_estadao.py new file mode 100644 index 0000000000..97fcea4b8a --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_estadao.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +estadao.com.br +''' + +from calibre.web.feeds.news import BasicNewsRecipe + + +class Estadao(BasicNewsRecipe): + title = 'O Estado de S. Paulo' + __author__ = 'Darko Miletic' + description = 'News from Brasil' + language = _('Spanish') + oldest_article = 2 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'utf8' + cover_url = 'http://www.estadao.com.br/img/logo_estadao.png' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Brasil' + , '--publisher' , title + ] + + keep_only_tags = [dict(name='div', attrs={'id':'c1'})] + + remove_tags = [ + dict(name=['script','object','form','ul']) + ,dict(name='div', attrs={'id':['votacao','estadaohoje']}) + ,dict(name='p', attrs={'id':'ctrl_texto'}) + ,dict(name='p', attrs={'class':'texto'}) + ] + + feeds = [ + (u'Manchetes Estadao', u'http://www.estadao.com.br/rss/manchetes.xml') + ,(u'Ultimas noticias', u'http://www.estadao.com.br/rss/ultimas.xml') + ,(u'Nacional', u'http://www.estadao.com.br/rss/nacional.xml') + ,(u'Internacional', u'http://www.estadao.com.br/rss/internacional.xml') + ,(u'Cidades', u'http://www.estadao.com.br/rss/cidades.xml') + ,(u'Esportes', u'http://www.estadao.com.br/rss/esportes.xml') + ,(u'Arte & Lazer', u'http://www.estadao.com.br/rss/arteelazer.xml') + ,(u'Economia', u'http://www.estadao.com.br/rss/economia.xml') + ,(u'Vida &', u'http://www.estadao.com.br/rss/vidae.xml') + ] + + def preprocess_html(self, soup): + ifr = soup.find('iframe') + if ifr: + ifr.extract() + return soup diff --git a/src/calibre/web/feeds/recipes/recipe_exiled.py b/src/calibre/web/feeds/recipes/recipe_exiled.py new file mode 100644 index 0000000000..e70e047e0d --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_exiled.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +exiledonline.com +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class Exiled(BasicNewsRecipe): + title = 'Exiled Online' + __author__ = 'Darko Miletic' + description = "Mankind's only alternative since 1997 - Formerly known as The eXile" + publisher = 'Exiled Online' + language = _('English') + category = 'news, politics, international' + oldest_article = 15 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'utf8' + remove_javascript = True + cover_url = 'http://exiledonline.com/wp-content/themes/exiledonline_theme/images/header-sm.gif' + + html2lrf_options = [ + '--comment' , description + , '--category' , category + , '--publisher' , publisher + ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + + keep_only_tags = [dict(name='div', attrs={'id':'main'})] + + remove_tags = [ + dict(name=['object','link']) + ,dict(name='div', attrs={'class':'info'}) + ,dict(name='div', attrs={'id':['comments','navig']}) + ] + + + feeds = [(u'Articles', u'http://exiledonline.com/feed/' )] + + def preprocess_html(self, soup): + for item in soup.findAll(style=True): + del item['style'] + mtag = '\n<meta http-equiv="Content-Language" content="en"/>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n' + soup.head.insert(0,mtag) + return soup + diff --git a/src/calibre/web/feeds/recipes/recipe_faznet.py b/src/calibre/web/feeds/recipes/recipe_faznet.py index 5efe7ec9e6..ceeeba6cd1 100644 --- a/src/calibre/web/feeds/recipes/recipe_faznet.py +++ b/src/calibre/web/feeds/recipes/recipe_faznet.py @@ -11,8 +11,9 @@ class FazNet(BasicNewsRecipe): title = 'FAZ NET' __author__ = 'Kovid Goyal' - description = '"Frankfurter Allgemeine Zeitung' - use_embedded_content = False + description = 'Frankfurter Allgemeine Zeitung' + use_embedded_content = False + language = _('German') max_articles_per_feed = 30 preprocess_regexps = [ diff --git a/src/calibre/web/feeds/recipes/recipe_financial_times.py b/src/calibre/web/feeds/recipes/recipe_financial_times.py index 5bf21d20fe..fe2956f572 100644 --- a/src/calibre/web/feeds/recipes/recipe_financial_times.py +++ b/src/calibre/web/feeds/recipes/recipe_financial_times.py @@ -13,6 +13,7 @@ class FinancialTimes(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Financial world news' oldest_article = 2 + language = _('English') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_forbes.py b/src/calibre/web/feeds/recipes/recipe_forbes.py index 9fa281fa09..71dd817a5f 100644 --- a/src/calibre/web/feeds/recipes/recipe_forbes.py +++ b/src/calibre/web/feeds/recipes/recipe_forbes.py @@ -7,6 +7,7 @@ class Forbes(BasicNewsRecipe): __author__ = 'Darko Miletic' oldest_article = 30 max_articles_per_feed = 100 + language = _('English') no_stylesheets = True html2lrf_options = ['--base-font-size', '10'] diff --git a/src/calibre/web/feeds/recipes/recipe_freakonomics.py b/src/calibre/web/feeds/recipes/recipe_freakonomics.py index 704f7f727d..8846172e30 100644 --- a/src/calibre/web/feeds/recipes/recipe_freakonomics.py +++ b/src/calibre/web/feeds/recipes/recipe_freakonomics.py @@ -10,6 +10,7 @@ class Freakonomics(BasicNewsRecipe): title = 'Freakonomics Blog' description = 'The Hidden side of everything' __author__ = 'Kovid Goyal' + language = _('English') feeds = [('Blog', 'http://freakonomics.blogs.nytimes.com/feed/atom/')] diff --git a/src/calibre/web/feeds/recipes/recipe_ftd.py b/src/calibre/web/feeds/recipes/recipe_ftd.py index b2c0a8ef50..00c5081bd3 100644 --- a/src/calibre/web/feeds/recipes/recipe_ftd.py +++ b/src/calibre/web/feeds/recipes/recipe_ftd.py @@ -15,6 +15,7 @@ class FTheiseDe(BasicNewsRecipe): __author__ = 'Oliver Niesner' use_embedded_content = False timefmt = ' [%d %b %Y]' + language = _('German') max_articles_per_feed = 40 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_fudzilla.py b/src/calibre/web/feeds/recipes/recipe_fudzilla.py index eda7b6451a..d4c4429d70 100644 --- a/src/calibre/web/feeds/recipes/recipe_fudzilla.py +++ b/src/calibre/web/feeds/recipes/recipe_fudzilla.py @@ -12,6 +12,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class Fudzilla(BasicNewsRecipe): title = u'Fudzilla' __author__ = 'Darko Miletic' + language = _('English') description = 'Tech news' oldest_article = 7 max_articles_per_feed = 100 diff --git a/src/calibre/web/feeds/recipes/recipe_globe_and_mail.py b/src/calibre/web/feeds/recipes/recipe_globe_and_mail.py index a00e12eaaa..c50405096a 100644 --- a/src/calibre/web/feeds/recipes/recipe_globe_and_mail.py +++ b/src/calibre/web/feeds/recipes/recipe_globe_and_mail.py @@ -14,6 +14,7 @@ class GlobeAndMail(BasicNewsRecipe): title = 'Globe and Mail' __author__ = 'Kovid Goyal' + language = _('English') description = 'Canada\'s national newspaper' keep_only_tags = [dict(id='content')] remove_tags = [dict(attrs={'class':'nav'}), dict(id=['related', 'TPphoto', 'secondaryNav', 'articleBottomToolsHolder'])] diff --git a/src/calibre/web/feeds/recipes/recipe_granma.py b/src/calibre/web/feeds/recipes/recipe_granma.py new file mode 100644 index 0000000000..43cbd32ae1 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_granma.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>' +''' +granma.cubaweb.cu +''' +import urllib + + +from calibre.web.feeds.news import BasicNewsRecipe + +class Granma(BasicNewsRecipe): + title = 'Diario Granma' + __author__ = 'Darko Miletic' + language = _('Spanish') + description = 'Organo oficial del Comite Central del Partido Comunista de Cuba' + oldest_article = 2 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1252' + cover_url = 'http://www.granma.cubaweb.cu/imagenes/granweb229d.jpg' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Cuba' + , '--publisher' , title + , '--ignore-tables' + ] + + keep_only_tags = [dict(name='table', attrs={'height':'466'})] + + feeds = [(u'Noticias', u'http://www.granma.cubaweb.cu/noticias.xml' )] + + + def preprocess_html(self, soup): + del soup.body.table['style'] + rtag = soup.find('td', attrs={'height':'458'}) + if rtag: + del rtag['style'] + return soup + diff --git a/src/calibre/web/feeds/recipes/recipe_greader.py b/src/calibre/web/feeds/recipes/recipe_greader.py index 011718feae..f222a322f1 100644 --- a/src/calibre/web/feeds/recipes/recipe_greader.py +++ b/src/calibre/web/feeds/recipes/recipe_greader.py @@ -32,5 +32,6 @@ class GoogleReader(BasicNewsRecipe): soup = self.index_to_soup('http://www.google.com/reader/api/0/tag/list') for id in soup.findAll(True, attrs={'name':['id']}): url = id.contents[0] - feeds.append((re.search('/([^/]*)$', url).group(1), self.base_url + urllib.quote(url) + self.get_options)) + feeds.append((re.search('/([^/]*)$', url).group(1), + self.base_url + urllib.quote(url.encode('utf-8')) + self.get_options)) return feeds diff --git a/src/calibre/web/feeds/recipes/recipe_guardian.py b/src/calibre/web/feeds/recipes/recipe_guardian.py index 3fccd7c328..3876df630c 100644 --- a/src/calibre/web/feeds/recipes/recipe_guardian.py +++ b/src/calibre/web/feeds/recipes/recipe_guardian.py @@ -13,6 +13,7 @@ class Guardian(BasicNewsRecipe): title = u'The Guardian' __author__ = 'Seabound' + language = _('English') oldest_article = 7 max_articles_per_feed = 20 diff --git a/src/calibre/web/feeds/recipes/recipe_harpers.py b/src/calibre/web/feeds/recipes/recipe_harpers.py index 7649f6bd9b..e15263730d 100644 --- a/src/calibre/web/feeds/recipes/recipe_harpers.py +++ b/src/calibre/web/feeds/recipes/recipe_harpers.py @@ -10,6 +10,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class Harpers(BasicNewsRecipe): title = u"Harper's Magazine" __author__ = u'Darko Miletic' + language = _('English') description = u"Harper's Magazine: Founded June 1850." oldest_article = 30 max_articles_per_feed = 100 diff --git a/src/calibre/web/feeds/recipes/recipe_harpers_full.py b/src/calibre/web/feeds/recipes/recipe_harpers_full.py index c87faf195a..adf0bf82a3 100644 --- a/src/calibre/web/feeds/recipes/recipe_harpers_full.py +++ b/src/calibre/web/feeds/recipes/recipe_harpers_full.py @@ -15,6 +15,7 @@ class Harpers_full(BasicNewsRecipe): title = u"Harper's Magazine - articles from printed edition" __author__ = u'Darko Miletic' description = u"Harper's Magazine: Founded June 1850." + language = _('English') oldest_article = 30 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_heise.py b/src/calibre/web/feeds/recipes/recipe_heise.py index 9d2f230f6a..7dffa9b092 100644 --- a/src/calibre/web/feeds/recipes/recipe_heise.py +++ b/src/calibre/web/feeds/recipes/recipe_heise.py @@ -13,6 +13,7 @@ class HeiseDe(BasicNewsRecipe): title = 'heise' description = 'Computernews from Germany' __author__ = 'Oliver Niesner' + language = _('German') use_embedded_content = False timefmt = ' [%d %b %Y]' max_articles_per_feed = 40 diff --git a/src/calibre/web/feeds/recipes/recipe_iht.py b/src/calibre/web/feeds/recipes/recipe_iht.py index 4b962f523a..c30be70dea 100644 --- a/src/calibre/web/feeds/recipes/recipe_iht.py +++ b/src/calibre/web/feeds/recipes/recipe_iht.py @@ -11,6 +11,7 @@ from calibre.ptempfile import PersistentTemporaryFile class InternationalHeraldTribune(BasicNewsRecipe): title = u'The International Herald Tribune' __author__ = 'Derry FitzGerald' + language = _('English') oldest_article = 1 max_articles_per_feed = 10 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_infobae.py b/src/calibre/web/feeds/recipes/recipe_infobae.py index b6975d9a60..5acbcfa763 100644 --- a/src/calibre/web/feeds/recipes/recipe_infobae.py +++ b/src/calibre/web/feeds/recipes/recipe_infobae.py @@ -13,6 +13,7 @@ class Infobae(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Informacion Libre las 24 horas' oldest_article = 2 + language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_irish_times.py b/src/calibre/web/feeds/recipes/recipe_irish_times.py index 37defe5a80..089e8d974c 100644 --- a/src/calibre/web/feeds/recipes/recipe_irish_times.py +++ b/src/calibre/web/feeds/recipes/recipe_irish_times.py @@ -9,6 +9,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class IrishTimes(BasicNewsRecipe): title = u'The Irish Times' __author__ = 'Derry FitzGerald' + language = _('English') no_stylesheets = True remove_tags = [dict(name='div', attrs={'class':'footer'})] diff --git a/src/calibre/web/feeds/recipes/recipe_japan_times.py b/src/calibre/web/feeds/recipes/recipe_japan_times.py index 91d3604539..4a8c83a883 100644 --- a/src/calibre/web/feeds/recipes/recipe_japan_times.py +++ b/src/calibre/web/feeds/recipes/recipe_japan_times.py @@ -11,7 +11,8 @@ from calibre.web.feeds.news import BasicNewsRecipe class JapanTimes(BasicNewsRecipe): title = u'The Japan Times' __author__ = 'Darko Miletic' - description = 'News from Japan' + description = 'News from Japan' + language = _('English') oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_jb_online.py b/src/calibre/web/feeds/recipes/recipe_jb_online.py new file mode 100644 index 0000000000..c94ab25f05 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_jb_online.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +jbonline.terra.com.br +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class JBOnline(BasicNewsRecipe): + title = 'Jornal Brasileiro Online' + __author__ = 'Darko Miletic' + description = 'News from Brasil' + oldest_article = 2 + language = _('Spanish') + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1252' + cover_url = 'http://jbonline.terra.com.br/img/logo_01.gif' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Brasil' + , '--publisher' , title + ] + + keep_only_tags = [dict(name='div', attrs={'id':'corpoNoticia'})] + + remove_tags = [dict(name=['script','object','form'])] + + feeds = [(u'Todos as editorias', u'http://jbonline.terra.com.br/extra/rsstrjb.xml')] + + def preprocess_html(self, soup): + ifr = soup.find('iframe') + if ifr: + ifr.extract() + item = soup.find('div', attrs={'id':'corpoNoticia'}) + if item: + del item['style'] + return soup diff --git a/src/calibre/web/feeds/recipes/recipe_joelonsoftware.py b/src/calibre/web/feeds/recipes/recipe_joelonsoftware.py index 136dddf367..4f2f018708 100644 --- a/src/calibre/web/feeds/recipes/recipe_joelonsoftware.py +++ b/src/calibre/web/feeds/recipes/recipe_joelonsoftware.py @@ -12,6 +12,7 @@ class Joelonsoftware(BasicNewsRecipe): title = 'Joel on Software' __author__ = 'Darko Miletic' description = 'Painless Software Management' + language = _('English') no_stylesheets = True use_embedded_content = True diff --git a/src/calibre/web/feeds/recipes/recipe_jpost.py b/src/calibre/web/feeds/recipes/recipe_jpost.py index d183a388ff..d8a00037d5 100644 --- a/src/calibre/web/feeds/recipes/recipe_jpost.py +++ b/src/calibre/web/feeds/recipes/recipe_jpost.py @@ -1,37 +1,30 @@ -import re from calibre.web.feeds.news import BasicNewsRecipe class JerusalemPost(BasicNewsRecipe): - title = 'Jerusalem Post' + title = 'Jerusalem Post' description = 'News from Israel and the Middle East' use_embedded_content = False + language = _('English') __author__ = 'Kovid Goyal' max_articles_per_feed = 10 - - - - preprocess_regexps = [ (re.compile(i[0], re.IGNORECASE | re.DOTALL), i[1]) for i in - [ - (r'<HEAD>.*?</HEAD>' , lambda match : '<HEAD></HEAD>'), - (r'<BODY.*?>.*?<!-- start Entries -->', lambda match : '<BODY><!-- start Entries -->'), - (r'<!-- end Entries -->.*?</BODY>', lambda match : '</BODY>'), - (r'<script.*?>.*?</script>', lambda match : ''), - (r'<div class="apple-rss-article apple-rss-read" onclick=.*?<div class="apple-rss-article-body">', lambda match : ''), - (r'<img src=\'/images/logo_NWAnews.gif\' alt=\'NWAnews.com :: Northwest Arkansas\' News Source\'.*?>', lambda match : ''), - (r'<img src=\'/images/logo_adg.gif\'.*?>', lambda match : ''), - (r'<P CLASS="smallprint">.*?</body>', lambda match : '</body>'), - - ] - ] + no_stylesheets = True + remove_tags_before = {'class':'byline'} + remove_tags = [ + {'class':['artAdBlock clearboth', 'tbartop', 'divdot_vrttbox', + 'slideshow']}, + dict(id=['artFontButtons', 'artRelatedBlock']), + ] + remove_tags_after = {'id':'artTxtBlock'} feeds = [ ('Front Page', 'http://www.jpost.com/servlet/Satellite?pagename=JPost/Page/RSS&cid=1123495333346'), - ('Israel News', 'http://www.jpost.com/servlet/Satellite?pagename=JPost/Page/RSS&cid=1178443463156'), - ('Middle East News', 'http://www.jpost.com/servlet/Satellite?pagename=JPost/Page/RSS&cid=1123495333498'), - ('International News', 'http://www.jpost.com/servlet/Satellite?pagename=JPost/Page/RSS&cid=1178443463144'), - ('Editorials', 'http://www.jpost.com/servlet/Satellite?pagename=JPost/Page/RSS&cid=1123495333211'), + ('Israel News', 'http://www.jpost.com/servlet/Satellite?pagename=JPost/Page/RSS&cid=1178443463156'), + ('Middle East News', 'http://www.jpost.com/servlet/Satellite?pagename=JPost/Page/RSS&cid=1123495333498'), + ('International News', 'http://www.jpost.com/servlet/Satellite?pagename=JPost/Page/RSS&cid=1178443463144'), + ('Editorials', 'http://www.jpost.com/servlet/Satellite?pagename=JPost/Page/RSS&cid=1123495333211'), ] - def print_version(self, url): - return ('http://www.jpost.com/servlet/Satellite?cid=' + url.rpartition('&')[2] + '&pagename=JPost%2FJPArticle%2FPrinter') - + def postprocess_html(self, soup, first): + for tag in soup.findAll(name=['table', 'tr', 'td']): + tag.name = 'div' + return soup \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_juventudrebelde.py b/src/calibre/web/feeds/recipes/recipe_juventudrebelde.py new file mode 100644 index 0000000000..5fa9f45e41 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_juventudrebelde.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>' +''' +juventudrebelde.cu +''' +from calibre import strftime + +from calibre.web.feeds.news import BasicNewsRecipe + +class Juventudrebelde(BasicNewsRecipe): + title = 'Juventud Rebelde' + __author__ = 'Darko Miletic' + description = 'Diario de la Juventud Cubana' + oldest_article = 2 + language = _('Spanish') + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1252' + cover_url = strftime('http://www.juventudrebelde.cu/UserFiles/File/impreso/iportada-%Y-%m-%d.jpg') + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Cuba' + , '--publisher' , title + , '--ignore-tables' + ] + + keep_only_tags = [dict(name='div', attrs={'id':'noticia'})] + + feeds = [ + (u'Generales', u'http://www.juventudrebelde.cu/rss/generales.php' ) + ,(u'Cuba', u'http://www.juventudrebelde.cu/rss/generales.php?seccion=cuba' ) + ,(u'Internacionales', u'http://www.juventudrebelde.cu/rss/generales.php?seccion=internacionales' ) + ,(u'Opinion', u'http://www.juventudrebelde.cu/rss/generales.php?seccion=opinion' ) + ,(u'Cultura', u'http://www.juventudrebelde.cu/rss/generales.php?seccion=cultura' ) + ,(u'Deportes', u'http://www.juventudrebelde.cu/rss/generales.php?seccion=deportes' ) + ,(u'Lectura', u'http://www.juventudrebelde.cu/rss/generales.php?seccion=lectura' ) + ] + + diff --git a/src/calibre/web/feeds/recipes/recipe_juventudrebelde_english.py b/src/calibre/web/feeds/recipes/recipe_juventudrebelde_english.py new file mode 100644 index 0000000000..e7c1002323 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_juventudrebelde_english.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>' +''' +juventudrebelde.co.cu +''' +from calibre import strftime + +from calibre.web.feeds.news import BasicNewsRecipe + +class Juventudrebelde_english(BasicNewsRecipe): + title = 'Juventud Rebelde in english' + __author__ = 'Darko Miletic' + description = 'The newspaper of Cuban Youth' + language = _('English') + oldest_article = 2 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'iso-8859-1' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Cuba' + , '--publisher' , title + , '--ignore-tables' + ] + + keep_only_tags = [dict(name='div', attrs={'class':'read'})] + + feeds = [(u'All news', u'http://www.juventudrebelde.cip.cu/rss/all/' )] + + diff --git a/src/calibre/web/feeds/recipes/recipe_la_cuarta.py b/src/calibre/web/feeds/recipes/recipe_la_cuarta.py new file mode 100644 index 0000000000..e5576cd442 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_la_cuarta.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +lacuarta.cl +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class LaCuarta(BasicNewsRecipe): + title = 'La Cuarta' + __author__ = 'Darko Miletic' + description = 'El sitio de noticias online de Chile' + oldest_article = 2 + language = _('Spanish') + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1252' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Chile' + , '--publisher' , title + ] + + keep_only_tags = [dict(name='div', attrs={'class':'articulo desplegado'}) ] + + remove_tags = [ + dict(name='script') + ,dict(name='ul') + ,dict(name='div', attrs={'id':['toolbox','articleImageDisplayer','enviarAmigo']}) + ,dict(name='div', attrs={'class':['par ad-1','par ad-2']}) + ,dict(name='input') + ,dict(name='p', attrs={'id':['mensajeError','mensajeEnviandoNoticia','mensajeExito']}) + ,dict(name='strong', text='PUBLICIDAD') + ] + + + feeds = [(u'Noticias', u'http://lacuarta.cl/app/rss?sc=TEFDVUFSVEE=')] + + diff --git a/src/calibre/web/feeds/recipes/recipe_la_segunda.py b/src/calibre/web/feeds/recipes/recipe_la_segunda.py new file mode 100644 index 0000000000..7f5415806d --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_la_segunda.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +lasegunda.com +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class LaSegunda(BasicNewsRecipe): + title = 'La Segunda' + __author__ = 'Darko Miletic' + description = 'El sitio de noticias online de Chile' + language = _('Spanish') + oldest_article = 2 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1252' + cover_url = 'http://www.lasegunda.com/imagenes/logotipo_lasegunda_Oli.gif' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Chile' + , '--publisher' , title + , '--ignore-tables' + ] + + keep_only_tags = [dict(name='table')] + + feeds = [ + (u'Noticias de ultima hora', u'http://www.lasegunda.com/rss20/index.asp?canal=0') + ,(u'Politica', u'http://www.lasegunda.com/rss20/index.asp?canal=21') + ,(u'Cronica', u'http://www.lasegunda.com/rss20/index.asp?canal=20') + ,(u'Internacional', u'http://www.lasegunda.com/rss20/index.asp?canal=23') + ,(u'Deportes', u'http://www.lasegunda.com/rss20/index.asp?canal=24') + ,(u'Epectaculos/Cultura', u'http://www.lasegunda.com/rss20/index.asp?canal=25') + ,(u'Educacion', u'http://www.lasegunda.com/rss20/index.asp?canal=26') + ,(u'Ciencia y Tecnologia', u'http://www.lasegunda.com/rss20/index.asp?canal=27') + ,(u'Solidaridad', u'http://www.lasegunda.com/rss20/index.asp?canal=28') + ,(u'Buena Vida', u'http://www.lasegunda.com/rss20/index.asp?canal=32') + ] + + def print_version(self, url): + rest, sep, article_id = url.partition('index.asp?idnoticia=') + return u'http://www.lasegunda.com/edicionOnline/include/secciones/_detalle_impresion.asp?idnoticia=' + article_id + diff --git a/src/calibre/web/feeds/recipes/recipe_la_tercera.py b/src/calibre/web/feeds/recipes/recipe_la_tercera.py new file mode 100644 index 0000000000..65b0e630df --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_la_tercera.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +latercera.com +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class LaTercera(BasicNewsRecipe): + title = 'La Tercera' + __author__ = 'Darko Miletic' + description = 'El sitio de noticias online de Chile' + oldest_article = 2 + language = _('Spanish') + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1252' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Chile' + , '--publisher' , title + ] + + keep_only_tags = [dict(name='div', attrs={'class':'span-16 articulo border'}) ] + + remove_tags = [ + dict(name='script') + ,dict(name='ul') + ,dict(name='div', attrs={'id':['boxComentarios','shim','enviarAmigo']}) + ,dict(name='div', attrs={'class':['ad640','span-10 imgSet A','infoRelCol']}) + ,dict(name='input') + ,dict(name='p', attrs={'id':['mensajeError','mensajeEnviandoNoticia','mensajeExito']}) + ] + + + feeds = [ + (u'Noticias de ultima hora', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&ul=1') + ,(u'Pais', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=654') + ,(u'Mundo', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=678') + ,(u'Deportes', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=656') + ,(u'Negocios', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=655') + ,(u'Entretenimiento', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=661') + ,(u'Motores', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=665') + ,(u'Tendencias', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=659') + ,(u'Estilo', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=660') + ,(u'Educacion', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=657') + ] + + diff --git a/src/calibre/web/feeds/recipes/recipe_lanacion.py b/src/calibre/web/feeds/recipes/recipe_lanacion.py index 58d7672116..6cf2afdc89 100644 --- a/src/calibre/web/feeds/recipes/recipe_lanacion.py +++ b/src/calibre/web/feeds/recipes/recipe_lanacion.py @@ -13,6 +13,7 @@ class Lanacion(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Informacion actualizada las 24 horas, con noticias de Argentina y del mundo - Informate ya!' oldest_article = 2 + language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_lanacion_chile.py b/src/calibre/web/feeds/recipes/recipe_lanacion_chile.py new file mode 100644 index 0000000000..81f31f07d8 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_lanacion_chile.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +lanacion.cl +''' +import urllib + +from calibre.web.feeds.news import BasicNewsRecipe + +class LaNacionChile(BasicNewsRecipe): + title = 'La Nacion Chile' + __author__ = 'Darko Miletic' + description = 'El sitio de noticias online de Chile' + oldest_article = 2 + language = _('Spanish') + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1252' + cover_url = 'http://www.lanacion.cl/prontus_noticias_v2/imag/site/logo.gif' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Chile' + , '--publisher' , title + ] + + keep_only_tags = [dict(name='div', attrs={'class':'bloque'})] + + feeds = [(u'Noticias', u'http://www.lanacion.cl/rss.xml')] + + def print_version(self, url): + toprint = urllib.quote(url,':/') + return u'http://www.lanacion.cl/cgi-bx/imprimir.cgi?_URL=' + toprint + + def preprocess_html(self, soup): + del soup.body['onload'] + soup.head.base.extract() + item = soup.find('a', attrs={'href':'javascript:window.close()'}) + if item: + item.extract() + return soup + diff --git a/src/calibre/web/feeds/recipes/recipe_laprensa.py b/src/calibre/web/feeds/recipes/recipe_laprensa.py index 55bb8778a3..7c2567f8e6 100644 --- a/src/calibre/web/feeds/recipes/recipe_laprensa.py +++ b/src/calibre/web/feeds/recipes/recipe_laprensa.py @@ -14,6 +14,7 @@ class LaPrensa(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Informacion Libre las 24 horas' oldest_article = 7 + language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_latimes.py b/src/calibre/web/feeds/recipes/recipe_latimes.py index 71bbc14068..915a0946df 100644 --- a/src/calibre/web/feeds/recipes/recipe_latimes.py +++ b/src/calibre/web/feeds/recipes/recipe_latimes.py @@ -14,6 +14,7 @@ class LATimes(BasicNewsRecipe): description = u'News from Los Angeles' oldest_article = 7 max_articles_per_feed = 100 + language = _('English') no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_le_monde.py b/src/calibre/web/feeds/recipes/recipe_le_monde.py index d3ba64f18d..b543650200 100644 --- a/src/calibre/web/feeds/recipes/recipe_le_monde.py +++ b/src/calibre/web/feeds/recipes/recipe_le_monde.py @@ -16,6 +16,7 @@ class LeMonde(BasicNewsRecipe): __author__ = 'Mathieu Godlewski <mathieu at godlewski.fr>' description = 'Global news in french' oldest_article = 7 + language = _('French') max_articles_per_feed = 20 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_liberation.py b/src/calibre/web/feeds/recipes/recipe_liberation.py index 9f85433d11..9eb1436b38 100644 --- a/src/calibre/web/feeds/recipes/recipe_liberation.py +++ b/src/calibre/web/feeds/recipes/recipe_liberation.py @@ -12,6 +12,7 @@ class Liberation(BasicNewsRecipe): title = u'Liberation' __author__ = 'Darko Miletic' description = 'News from France' + language = _('French') oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_linux_magazine.py b/src/calibre/web/feeds/recipes/recipe_linux_magazine.py index 8b6d6ba81f..1ce96f9d19 100644 --- a/src/calibre/web/feeds/recipes/recipe_linux_magazine.py +++ b/src/calibre/web/feeds/recipes/recipe_linux_magazine.py @@ -12,7 +12,8 @@ from calibre.web.feeds.news import BasicNewsRecipe class LinuxMagazine(BasicNewsRecipe): title = u'Linux Magazine' __author__ = 'Darko Miletic' - description = 'Linux news' + description = 'Linux news' + language = _('English') oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_lrb.py b/src/calibre/web/feeds/recipes/recipe_lrb.py index 459e3580ce..bec6799ffe 100644 --- a/src/calibre/web/feeds/recipes/recipe_lrb.py +++ b/src/calibre/web/feeds/recipes/recipe_lrb.py @@ -14,6 +14,7 @@ class LondonReviewOfBooks(BasicNewsRecipe): description = u'Literary review publishing essay-length book reviews and topical articles on politics, literature, history, philosophy, science and the arts by leading writers and thinkers' oldest_article = 7 max_articles_per_feed = 100 + language = _('English') no_stylesheets = True use_embedded_content = False encoding = 'cp1252' diff --git a/src/calibre/web/feeds/recipes/recipe_moscow_times.py b/src/calibre/web/feeds/recipes/recipe_moscow_times.py index 6c4d249fad..e16d99284f 100644 --- a/src/calibre/web/feeds/recipes/recipe_moscow_times.py +++ b/src/calibre/web/feeds/recipes/recipe_moscow_times.py @@ -11,7 +11,8 @@ from calibre.web.feeds.news import BasicNewsRecipe class Moscowtimes(BasicNewsRecipe): title = u'The Moscow Times' __author__ = 'Darko Miletic' - description = 'News from Russia' + description = 'News from Russia' + language = _('English') oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_nasa.py b/src/calibre/web/feeds/recipes/recipe_nasa.py index 06bf82ca37..174750e972 100644 --- a/src/calibre/web/feeds/recipes/recipe_nasa.py +++ b/src/calibre/web/feeds/recipes/recipe_nasa.py @@ -31,6 +31,7 @@ class NASA(BasicNewsRecipe): title = 'NASA' timefmt = ' [%Y%b%d %H%M]' + language = _('English') description = 'News from NASA' __author__ = 'Scott Wxby & David Chen' no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_new_scientist.py b/src/calibre/web/feeds/recipes/recipe_new_scientist.py index dac7ab84fc..b87883ef6b 100644 --- a/src/calibre/web/feeds/recipes/recipe_new_scientist.py +++ b/src/calibre/web/feeds/recipes/recipe_new_scientist.py @@ -19,6 +19,7 @@ class NewScientist(BasicNewsRecipe): title = u'New Scientist - Online News' __author__ = 'Darko Miletic' description = 'News from Science' + language = _('English') oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_new_york_review_of_books.py b/src/calibre/web/feeds/recipes/recipe_new_york_review_of_books.py index e2bb4e0960..872381b9a1 100644 --- a/src/calibre/web/feeds/recipes/recipe_new_york_review_of_books.py +++ b/src/calibre/web/feeds/recipes/recipe_new_york_review_of_books.py @@ -15,6 +15,7 @@ class NewYorkReviewOfBooks(BasicNewsRecipe): title = u'New York Review of Books' description = u'Book reviews' + language = _('English') __author__ = 'Kovid Goyal' remove_tags_before = {'id':'container'} diff --git a/src/calibre/web/feeds/recipes/recipe_new_yorker.py b/src/calibre/web/feeds/recipes/recipe_new_yorker.py index f8ef5bc8cc..6134ab03bc 100644 --- a/src/calibre/web/feeds/recipes/recipe_new_yorker.py +++ b/src/calibre/web/feeds/recipes/recipe_new_yorker.py @@ -13,6 +13,7 @@ class NewYorker(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Best of the US journalism' oldest_article = 7 + language = _('English') max_articles_per_feed = 100 no_stylesheets = False use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_newsweek.py b/src/calibre/web/feeds/recipes/recipe_newsweek.py index b4de7c5762..43b7065fa5 100644 --- a/src/calibre/web/feeds/recipes/recipe_newsweek.py +++ b/src/calibre/web/feeds/recipes/recipe_newsweek.py @@ -13,6 +13,7 @@ class Newsweek(BasicNewsRecipe): __author__ = 'Kovid Goyal' description = 'Weekly news and current affairs in the US' no_stylesheets = True + language = _('English') extra_css = '#content { font:serif 12pt; }\n.story {font:12pt}\n.HorizontalHeader {font:18pt}\n.deck {font:16pt}' keep_only_tags = [dict(name='div', id='content')] diff --git a/src/calibre/web/feeds/recipes/recipe_nspm.py b/src/calibre/web/feeds/recipes/recipe_nspm.py index b06df23a75..d828636545 100644 --- a/src/calibre/web/feeds/recipes/recipe_nspm.py +++ b/src/calibre/web/feeds/recipes/recipe_nspm.py @@ -14,6 +14,7 @@ class Nspm(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Casopis za politicku teoriju i drustvena istrazivanja' oldest_article = 7 + language = _('Serbian') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_nspm_int.py b/src/calibre/web/feeds/recipes/recipe_nspm_int.py index b474a5e2a9..ef5aae883a 100644 --- a/src/calibre/web/feeds/recipes/recipe_nspm_int.py +++ b/src/calibre/web/feeds/recipes/recipe_nspm_int.py @@ -14,6 +14,7 @@ class Nspm_int(BasicNewsRecipe): description = 'Magazine dedicated to political theory and sociological research' oldest_article = 20 max_articles_per_feed = 100 + language = _('English') no_stylesheets = True use_embedded_content = False INDEX = 'http://www.nspm.rs/?alphabet=l' diff --git a/src/calibre/web/feeds/recipes/recipe_nytimes.py b/src/calibre/web/feeds/recipes/recipe_nytimes.py index 43f0481e61..270bd5d499 100644 --- a/src/calibre/web/feeds/recipes/recipe_nytimes.py +++ b/src/calibre/web/feeds/recipes/recipe_nytimes.py @@ -14,6 +14,7 @@ class NYTimesMobile(BasicNewsRecipe): title = 'The New York Times' __author__ = 'Kovid Goyal' + language = _('English') description = 'Daily news from the New York Times (mobile version)' timefmt = ' [%a, %d %b, %Y]' multithreaded_fetch = True diff --git a/src/calibre/web/feeds/recipes/recipe_nytimes_sub.py b/src/calibre/web/feeds/recipes/recipe_nytimes_sub.py index fc688512b9..4a4286b335 100644 --- a/src/calibre/web/feeds/recipes/recipe_nytimes_sub.py +++ b/src/calibre/web/feeds/recipes/recipe_nytimes_sub.py @@ -14,6 +14,7 @@ class NYTimes(BasicNewsRecipe): title = 'The New York Times (subscription)' __author__ = 'Kovid Goyal' + language = _('English') description = 'Daily news from the New York Times (subscription version)' timefmt = ' [%a, %d %b, %Y]' needs_subscription = True diff --git a/src/calibre/web/feeds/recipes/recipe_o_globo.py b/src/calibre/web/feeds/recipes/recipe_o_globo.py new file mode 100644 index 0000000000..1331ea86a3 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_o_globo.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>' +''' +oglobo.globo.com +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class OGlobo(BasicNewsRecipe): + title = 'O Globo' + __author__ = 'Darko Miletic' + description = 'News from Brasil' + oldest_article = 2 + max_articles_per_feed = 100 + language = _('Spanish') + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1252' + cover_url = 'http://oglobo.globo.com/_img/o-globo.png' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Brasil' + , '--publisher' , title + ] + + keep_only_tags = [dict(name='div', attrs={'id':'ltintb'})] + + remove_tags = [ + dict(name='script') + ,dict(name='object') + ,dict(name='form') + ,dict(name='div', attrs={'id':['linksPatGoogle','rdpm','cor','com','env','rcm_st']}) + ,dict(name='div', attrs={'class':'box-zap-anu2'}) + ,dict(name='a') + ,dict(name='link') + ] + + + feeds = [ + (u'Todos os canais', u'http://oglobo.globo.com/rss/plantao.xml') + ,(u'Ciencia', u'http://oglobo.globo.com/rss/plantaociencia.xml') + ,(u'Educacao', u'http://oglobo.globo.com/rss/plantaoeducacao.xml') + ,(u'Opiniao', u'http://oglobo.globo.com/rss/plantaoopiniao.xml') + ,(u'Sao Paulo', u'http://oglobo.globo.com/rss/plantaosaopaulo.xml') + ,(u'Viagem', u'http://oglobo.globo.com/rss/plantaoviagem.xml') + ,(u'Cultura', u'http://oglobo.globo.com/rss/plantaocultura.xml') + ,(u'Esportes', u'http://oglobo.globo.com/rss/plantaoesportes.xml') + ,(u'Mundo', u'http://oglobo.globo.com/rss/plantaomundo.xml') + ,(u'Pais', u'http://oglobo.globo.com/rss/plantaopais.xml') + ,(u'Rio', u'http://oglobo.globo.com/rss/plantaorio.xml') + ,(u'Saude', u'http://oglobo.globo.com/rss/plantaosaude.xml') + ,(u'Viver Melhor', u'http://oglobo.globo.com/rss/plantaovivermelhor.xml') + ,(u'Economia', u'http://oglobo.globo.com/rss/plantaoeconomia.xml') + ,(u'Tecnologia', u'http://oglobo.globo.com/rss/plantaotecnologia.xml') + ] diff --git a/src/calibre/web/feeds/recipes/recipe_outlook_india.py b/src/calibre/web/feeds/recipes/recipe_outlook_india.py index db8ad900ab..e84a53f04c 100644 --- a/src/calibre/web/feeds/recipes/recipe_outlook_india.py +++ b/src/calibre/web/feeds/recipes/recipe_outlook_india.py @@ -14,6 +14,7 @@ class OutlookIndia(BasicNewsRecipe): title = 'Outlook India' __author__ = 'Kovid Goyal' description = 'Weekly news magazine focussed on India.' + language = _('English') recursions = 1 match_regexp = r'full.asp.*&pn=\d+' html2lrf_options = ['--ignore-tables'] diff --git a/src/calibre/web/feeds/recipes/recipe_pagina12.py b/src/calibre/web/feeds/recipes/recipe_pagina12.py index 8b427e8ad1..8428a9a35f 100644 --- a/src/calibre/web/feeds/recipes/recipe_pagina12.py +++ b/src/calibre/web/feeds/recipes/recipe_pagina12.py @@ -12,7 +12,8 @@ from calibre.web.feeds.news import BasicNewsRecipe class Pagina12(BasicNewsRecipe): title = u'Pagina/12' __author__ = 'Darko Miletic' - description = 'Noticias de Argentina y el resto del mundo' + description = 'Noticias de Argentina y el resto del mundo' + language = _('Spanish') oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_portfolio.py b/src/calibre/web/feeds/recipes/recipe_portfolio.py index a8cad99d17..83fd665157 100644 --- a/src/calibre/web/feeds/recipes/recipe_portfolio.py +++ b/src/calibre/web/feeds/recipes/recipe_portfolio.py @@ -13,6 +13,7 @@ class Portfolio(BasicNewsRecipe): title = 'Portfolio' __author__ = 'JTravers' description = 'Conde Nast Portfolio: For the businessman.' + language = _('English') use_embedded_content = True timefmt = ' [%a, %b %d, %Y]' html2lrf_options = ['--ignore-tables'] diff --git a/src/calibre/web/feeds/recipes/recipe_reuters.py b/src/calibre/web/feeds/recipes/recipe_reuters.py index 9fe57ceeb4..3a2d4d6de7 100644 --- a/src/calibre/web/feeds/recipes/recipe_reuters.py +++ b/src/calibre/web/feeds/recipes/recipe_reuters.py @@ -9,6 +9,7 @@ class Reuters(BasicNewsRecipe): description = 'Global news' __author__ = 'Kovid Goyal' use_embedded_content = False + language = _('English') max_articles_per_feed = 10 diff --git a/src/calibre/web/feeds/recipes/recipe_san_fran_chronicle.py b/src/calibre/web/feeds/recipes/recipe_san_fran_chronicle.py index 8682b743a4..7d93d7a5db 100644 --- a/src/calibre/web/feeds/recipes/recipe_san_fran_chronicle.py +++ b/src/calibre/web/feeds/recipes/recipe_san_fran_chronicle.py @@ -11,7 +11,8 @@ from calibre.web.feeds.news import BasicNewsRecipe class SanFranciscoChronicle(BasicNewsRecipe): title = u'San Francisco Chronicle' __author__ = u'Darko Miletic' - description = u'San Francisco news' + description = u'San Francisco news' + language = _('English') oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_science_aas.py b/src/calibre/web/feeds/recipes/recipe_science_aas.py index 0ff14afacd..2b0c706a0d 100644 --- a/src/calibre/web/feeds/recipes/recipe_science_aas.py +++ b/src/calibre/web/feeds/recipes/recipe_science_aas.py @@ -10,6 +10,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class ScienceAAS(BasicNewsRecipe): title = u'Science AAAS' __author__ = u'Darko Miletic' + language = _('English') description = u'The best in science news, commentary, and research' oldest_article = 7 max_articles_per_feed = 100 diff --git a/src/calibre/web/feeds/recipes/recipe_science_news.py b/src/calibre/web/feeds/recipes/recipe_science_news.py index 1ec29a69c6..8828ef9b22 100644 --- a/src/calibre/web/feeds/recipes/recipe_science_news.py +++ b/src/calibre/web/feeds/recipes/recipe_science_news.py @@ -12,6 +12,7 @@ class Sciencenews(BasicNewsRecipe): __author__ = u'Darko Miletic' description = u"Science News is an award-winning weekly newsmagazine covering the most important research in all fields of science. Its 16 pages each week are packed with short, accurate articles that appeal to both general readers and scientists. Published since 1922, the magazine now reaches about 150,000 subscribers and more than 1 million readers. These are the latest News Items from Science News." oldest_article = 30 + language = _('English') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_sciencedaily.py b/src/calibre/web/feeds/recipes/recipe_sciencedaily.py index 2b26de79c8..15293a12e3 100644 --- a/src/calibre/web/feeds/recipes/recipe_sciencedaily.py +++ b/src/calibre/web/feeds/recipes/recipe_sciencedaily.py @@ -12,6 +12,7 @@ class ScienceDaily(BasicNewsRecipe): __author__ = u'Darko Miletic' description = u"Breaking science news and articles on global warming, extrasolar planets, stem cells, bird flu, autism, nanotechnology, dinosaurs, evolution -- the latest discoveries in astronomy, anthropology, biology, chemistry, climate & environment, computers, engineering, health & medicine, math, physics, psychology, technology, and more -- from the world's leading universities and research organizations." oldest_article = 7 + language = _('English') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_scientific_american.py b/src/calibre/web/feeds/recipes/recipe_scientific_american.py index 468e799d44..e2bce46f2f 100644 --- a/src/calibre/web/feeds/recipes/recipe_scientific_american.py +++ b/src/calibre/web/feeds/recipes/recipe_scientific_american.py @@ -14,6 +14,7 @@ class ScientificAmerican(BasicNewsRecipe): title = u'Scientific American' description = u'Popular science. Monthly magazine.' __author__ = 'Kovid Goyal' + language = _('English') oldest_article = 30 max_articles_per_feed = 100 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_security_watch.py b/src/calibre/web/feeds/recipes/recipe_security_watch.py index 4975628dcc..7b111da208 100644 --- a/src/calibre/web/feeds/recipes/recipe_security_watch.py +++ b/src/calibre/web/feeds/recipes/recipe_security_watch.py @@ -12,6 +12,7 @@ class SecurityWatch(BasicNewsRecipe): filter_regexps = [r'feedads\.googleadservices\.com'] filter_regexps = [r'ad\.doubleclick'] filter_regexps = [r'advert'] + language = _('English') remove_tags = [dict(id='topBannerContainer'), dict(id='topBannerSmall'), diff --git a/src/calibre/web/feeds/recipes/recipe_shacknews.py b/src/calibre/web/feeds/recipes/recipe_shacknews.py index 878384f63b..7006bc8a7f 100644 --- a/src/calibre/web/feeds/recipes/recipe_shacknews.py +++ b/src/calibre/web/feeds/recipes/recipe_shacknews.py @@ -7,6 +7,7 @@ class Shacknews(BasicNewsRecipe): title = u'Shacknews' oldest_article = 7 max_articles_per_feed = 100 + language = _('English') no_stylesheets = True remove_tags = [dict(name='div', attrs={'class': ['nuggets', 'comments']}), dict(name='p', attrs={'class': 'videoembed'})] diff --git a/src/calibre/web/feeds/recipes/recipe_smh.py b/src/calibre/web/feeds/recipes/recipe_smh.py index 444b211084..f330cc9d8a 100644 --- a/src/calibre/web/feeds/recipes/recipe_smh.py +++ b/src/calibre/web/feeds/recipes/recipe_smh.py @@ -16,6 +16,7 @@ class SMH(BasicNewsRecipe): title = 'Sydney Morning Herald' description = 'Business News, World News and Breaking News in Australia' __author__ = 'Kovid Goyal' + language = _('English') def get_browser(self): br = BasicNewsRecipe.get_browser() diff --git a/src/calibre/web/feeds/recipes/recipe_spiegel_int.py b/src/calibre/web/feeds/recipes/recipe_spiegel_int.py index 7ee8a9f258..3326e2b5ca 100644 --- a/src/calibre/web/feeds/recipes/recipe_spiegel_int.py +++ b/src/calibre/web/feeds/recipes/recipe_spiegel_int.py @@ -14,6 +14,7 @@ class Spiegel_int(BasicNewsRecipe): description = "News and POV from Europe's largest newsmagazine" oldest_article = 7 max_articles_per_feed = 100 + language = _('English') no_stylesheets = True use_embedded_content = False cover_url = 'http://www.spiegel.de/static/sys/v8/headlines/spiegelonline.gif' diff --git a/src/calibre/web/feeds/recipes/recipe_spiegelde.py b/src/calibre/web/feeds/recipes/recipe_spiegelde.py index f13c76639a..c45db73972 100644 --- a/src/calibre/web/feeds/recipes/recipe_spiegelde.py +++ b/src/calibre/web/feeds/recipes/recipe_spiegelde.py @@ -16,6 +16,7 @@ class SpeigelOnline(BasicNewsRecipe): description = 'Nachrichten des Magazins Der Spiegel' __author__ = 'Kovid Goyal' use_embedded_content = False + language = _('German') timefmt = ' [ %Y-%m-%d %a]' max_articles_per_feed = 40 no_stylesheets = True diff --git a/src/calibre/web/feeds/recipes/recipe_st_petersburg_times.py b/src/calibre/web/feeds/recipes/recipe_st_petersburg_times.py index 8734136752..7de4efa80e 100644 --- a/src/calibre/web/feeds/recipes/recipe_st_petersburg_times.py +++ b/src/calibre/web/feeds/recipes/recipe_st_petersburg_times.py @@ -17,6 +17,7 @@ class PetersburgTimes(BasicNewsRecipe): max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False + language = _('Russian') INDEX = 'http://www.sptimes.ru' def parse_index(self): diff --git a/src/calibre/web/feeds/recipes/recipe_sueddeutsche.py b/src/calibre/web/feeds/recipes/recipe_sueddeutsche.py index fa97b73c80..028707b61c 100644 --- a/src/calibre/web/feeds/recipes/recipe_sueddeutsche.py +++ b/src/calibre/web/feeds/recipes/recipe_sueddeutsche.py @@ -16,6 +16,7 @@ class Sueddeutsche(BasicNewsRecipe): use_embedded_content = False timefmt = ' [%d %b %Y]' max_articles_per_feed = 40 + language = _('German') no_stylesheets = True encoding = 'latin1' remove_tags_after = [dict(name='div', attrs={'class':'artikelBox navigatorBox'})] diff --git a/src/calibre/web/feeds/recipes/recipe_telegraph_uk.py b/src/calibre/web/feeds/recipes/recipe_telegraph_uk.py index 5bfb1c3580..7ff0815ae1 100644 --- a/src/calibre/web/feeds/recipes/recipe_telegraph_uk.py +++ b/src/calibre/web/feeds/recipes/recipe_telegraph_uk.py @@ -15,6 +15,7 @@ class TelegraphUK(BasicNewsRecipe): oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True + language = _('English') use_embedded_content = False keep_only_tags = [ diff --git a/src/calibre/web/feeds/recipes/recipe_telepolis.py b/src/calibre/web/feeds/recipes/recipe_telepolis.py index b25554431f..41db3f4631 100644 --- a/src/calibre/web/feeds/recipes/recipe_telepolis.py +++ b/src/calibre/web/feeds/recipes/recipe_telepolis.py @@ -14,6 +14,7 @@ class Telepolis(BasicNewsRecipe): description = 'News from Germany in German' oldest_article = 2 max_articles_per_feed = 100 + language = _('German') no_stylesheets = True use_embedded_content = False encoding = 'utf-8' diff --git a/src/calibre/web/feeds/recipes/recipe_teleread.py b/src/calibre/web/feeds/recipes/recipe_teleread.py index 06d66720fd..1bfd38ea85 100644 --- a/src/calibre/web/feeds/recipes/recipe_teleread.py +++ b/src/calibre/web/feeds/recipes/recipe_teleread.py @@ -14,6 +14,7 @@ class Teleread(BasicNewsRecipe): title = 'Teleread Blog' description = 'News & views on e-books, libraries, publishing and related topics' __author__ = 'Kovid Goyal' + language = _('English') feeds = [('Entries', 'http://www.teleread.org/feed/')] diff --git a/src/calibre/web/feeds/recipes/recipe_the_age.py b/src/calibre/web/feeds/recipes/recipe_the_age.py index 8bedc50cd5..dbc7427c1e 100644 --- a/src/calibre/web/feeds/recipes/recipe_the_age.py +++ b/src/calibre/web/feeds/recipes/recipe_the_age.py @@ -16,6 +16,7 @@ class TheAge(BasicNewsRecipe): title = 'The Age' description = 'Business News, World News and Breaking News in Melbourne, Australia' __author__ = 'Matthew Briggs' + language = _('English') def get_browser(self): br = BasicNewsRecipe.get_browser() diff --git a/src/calibre/web/feeds/recipes/recipe_the_nation.py b/src/calibre/web/feeds/recipes/recipe_the_nation.py index ed21415efd..9b2e48e39e 100644 --- a/src/calibre/web/feeds/recipes/recipe_the_nation.py +++ b/src/calibre/web/feeds/recipes/recipe_the_nation.py @@ -14,6 +14,7 @@ class Thenation(BasicNewsRecipe): oldest_article = 120 max_articles_per_feed = 100 no_stylesheets = True + language = _('English') use_embedded_content = False simultaneous_downloads = 1 delay = 1 diff --git a/src/calibre/web/feeds/recipes/recipe_the_oz.py b/src/calibre/web/feeds/recipes/recipe_the_oz.py new file mode 100644 index 0000000000..351c76a1c4 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_the_oz.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2009, Matthew Briggs' +__docformat__ = 'restructuredtext en' + +''' +http://www.theaustralian.news.com.au/ +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class DailyTelegraph(BasicNewsRecipe): + title = u'The Australian' + __author__ = u'Matthew Briggs' + description = u'National broadsheet newspaper from down under - colloquially known as The Oz' + language = _('English') + oldest_article = 2 + max_articles_per_feed = 10 + remove_javascript = True + no_stylesheets = True + encoding = 'utf8' + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Australia' + , '--publisher' , title + ] + + keep_only_tags = [ + dict(name='h1', attrs={'class':'section-heading'}) + ,dict(name='div', attrs={'id':'article'}) + ] + + remove_tags = [dict(name=['object','link'])] + + feeds = [ + (u'News', u'http://feeds.news.com.au/public/rss/2.0/aus_news_807.xml'), + (u'World News', u'http://feeds.news.com.au/public/rss/2.0/aus_world_808.xml'), + (u'Opinion', u'http://feeds.news.com.au/public/rss/2.0/aus_opinion_58.xml'), + (u'Business', u'http://feeds.news.com.au/public/rss/2.0/aus_business_811.xml'), + (u'Media', u'http://feeds.news.com.au/public/rss/2.0/aus_media_57.xml'), + (u'Higher Education', u'http://feeds.news.com.au/public/rss/2.0/aus_higher_education_56.xml'), + (u'The Arts', u'http://feeds.news.com.au/public/rss/2.0/aus_arts_51.xml'), + (u'Commercial Property', u'http://feeds.news.com.au/public/rss/2.0/aus_business_commercial_property_708.xml'), + (u'The Nation', u'http://feeds.news.com.au/public/rss/2.0/aus_the_nation_62.xml'), + (u'Sport', u'http://feeds.news.com.au/public/rss/2.0/aus_sport_61.xml'), + (u'Travel', u'http://feeds.news.com.au/public/rss/2.0/aus_travel_and_indulgence_63.xml'), + (u'Defence', u'http://feeds.news.com.au/public/rss/2.0/aus_defence_54.xml'), + (u'Aviation', u'http://feeds.news.com.au/public/rss/2.0/aus_business_aviation_706.xml'), + (u'Mining', u'http://feeds.news.com.au/public/rss/2.0/aus_business_mining_704.xml'), + (u'Climate', u'http://feeds.news.com.au/public/rss/2.0/aus_climate_809.xml'), + (u'Property', u'http://feeds.news.com.au/public/rss/2.0/aus_property_59.xml'), + (u'US Election', u'http://feeds.news.com.au/public/rss/2.0/aus_uselection_687.xml') + ] diff --git a/src/calibre/web/feeds/recipes/recipe_the_scotsman.py b/src/calibre/web/feeds/recipes/recipe_the_scotsman.py index 78ddb46fdb..c42bc4aed7 100644 --- a/src/calibre/web/feeds/recipes/recipe_the_scotsman.py +++ b/src/calibre/web/feeds/recipes/recipe_the_scotsman.py @@ -16,6 +16,7 @@ class TheScotsman(BasicNewsRecipe): max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False + language = _('English') simultaneous_downloads = 1 keep_only_tags = [dict(name='div', attrs={'id':'viewarticle'})] diff --git a/src/calibre/web/feeds/recipes/recipe_themarketticker.py b/src/calibre/web/feeds/recipes/recipe_themarketticker.py index 946369c8a9..b6cf752e23 100644 --- a/src/calibre/web/feeds/recipes/recipe_themarketticker.py +++ b/src/calibre/web/feeds/recipes/recipe_themarketticker.py @@ -14,6 +14,7 @@ class Themarketticker(BasicNewsRecipe): description = 'Commentary On The Capital Markets' oldest_article = 7 max_articles_per_feed = 100 + language = _('English') no_stylesheets = True use_embedded_content = True html2lrf_options = [ '--comment' , description diff --git a/src/calibre/web/feeds/recipes/recipe_time_magazine.py b/src/calibre/web/feeds/recipes/recipe_time_magazine.py index 026aa233db..bceac5fd69 100644 --- a/src/calibre/web/feeds/recipes/recipe_time_magazine.py +++ b/src/calibre/web/feeds/recipes/recipe_time_magazine.py @@ -15,6 +15,7 @@ class Time(BasicNewsRecipe): oldest_article = 7 max_articles_per_feed = 100 no_stylesheets = True + language = _('English') use_embedded_content = False keep_only_tags = [dict(name='div', attrs={'class':'tout1'})] diff --git a/src/calibre/web/feeds/recipes/recipe_times_online.py b/src/calibre/web/feeds/recipes/recipe_times_online.py index e57b331820..45e9a1e10e 100644 --- a/src/calibre/web/feeds/recipes/recipe_times_online.py +++ b/src/calibre/web/feeds/recipes/recipe_times_online.py @@ -16,6 +16,7 @@ class TimesOnline(BasicNewsRecipe): max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False + language = _('English') simultaneous_downloads = 1 remove_tags_after = dict(name='div', attrs={'class':'bg-666'}) diff --git a/src/calibre/web/feeds/recipes/recipe_tomshardware.py b/src/calibre/web/feeds/recipes/recipe_tomshardware.py index b0b155666f..2e4f5cfb9e 100644 --- a/src/calibre/web/feeds/recipes/recipe_tomshardware.py +++ b/src/calibre/web/feeds/recipes/recipe_tomshardware.py @@ -15,6 +15,7 @@ class Tomshardware(BasicNewsRecipe): description = 'Hardware reviews and News' no_stylesheets = True needs_subscription = True + language = _('English') INDEX = 'http://www.tomshardware.com' LOGIN = 'http://www.tomshardware.com/membres/?r=%2Fus%2F#loginForm' cover_url = 'http://img.bestofmedia.com/img/tomshardware/design/tomshardware.jpg' diff --git a/src/calibre/web/feeds/recipes/recipe_tomshardware_de.py b/src/calibre/web/feeds/recipes/recipe_tomshardware_de.py index 78d820e246..52f1583408 100644 --- a/src/calibre/web/feeds/recipes/recipe_tomshardware_de.py +++ b/src/calibre/web/feeds/recipes/recipe_tomshardware_de.py @@ -6,7 +6,6 @@ Fetch tomshardware. ''' from calibre.web.feeds.news import BasicNewsRecipe -import re class TomsHardwareDe(BasicNewsRecipe): @@ -17,6 +16,7 @@ class TomsHardwareDe(BasicNewsRecipe): use_embedded_content = False timefmt = ' [%d %b %Y]' max_articles_per_feed = 50 + language = _('German') no_stylesheets = True encoding = 'utf-8' diff --git a/src/calibre/web/feeds/recipes/recipe_upi.py b/src/calibre/web/feeds/recipes/recipe_upi.py index d29c34f769..5a96df7b48 100644 --- a/src/calibre/web/feeds/recipes/recipe_upi.py +++ b/src/calibre/web/feeds/recipes/recipe_upi.py @@ -12,7 +12,7 @@ class UnitedPressInternational(BasicNewsRecipe): title = 'United Press International' max_articles_per_feed = 15 html2lrf_options = ['--override-css= "H1 {font-family: Arial; font-weight: bold; color: #000000; size: 10pt;}"'] - + language = _('English') preprocess_regexps = [ (re.compile(i[0], re.IGNORECASE | re.DOTALL), i[1]) for i in [ diff --git a/src/calibre/web/feeds/recipes/recipe_usatoday.py b/src/calibre/web/feeds/recipes/recipe_usatoday.py index 6712ad2028..dd14cd01b4 100644 --- a/src/calibre/web/feeds/recipes/recipe_usatoday.py +++ b/src/calibre/web/feeds/recipes/recipe_usatoday.py @@ -15,6 +15,7 @@ class USAToday(BasicNewsRecipe): timefmt = ' [%d %b %Y]' max_articles_per_feed = 20 no_stylesheets = True + language = _('English') extra_css = ''' .inside-head { font: x-large bold } .inside-head2 { font: x-large bold } diff --git a/src/calibre/web/feeds/recipes/recipe_utne.py b/src/calibre/web/feeds/recipes/recipe_utne.py index eb22c21315..2eed5a411e 100644 --- a/src/calibre/web/feeds/recipes/recipe_utne.py +++ b/src/calibre/web/feeds/recipes/recipe_utne.py @@ -17,6 +17,7 @@ class Utne(BasicNewsRecipe): max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False + language = _('English') cover_url = 'http://www.utne.com/images/template/logo.gif' diff --git a/src/calibre/web/feeds/recipes/recipe_vijesti.py b/src/calibre/web/feeds/recipes/recipe_vijesti.py new file mode 100644 index 0000000000..beb6f64f65 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_vijesti.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>' + +''' +vijesti.cg.yu +''' + +import string,re + +from calibre.web.feeds.news import BasicNewsRecipe + +class Vijesti(BasicNewsRecipe): + title = 'Vijesti' + __author__ = 'Darko Miletic' + description = 'News from Montenegro' + oldest_article = 2 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + encoding = 'cp1250' + cover_url = 'http://www.vijesti.cg.yu/img/logo.gif' + + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] + + html2lrf_options = [ + '--comment' , description + , '--category' , 'news, Montenegro' + , '--publisher' , 'Daily Press Vijesti' + ] + + keep_only_tags = [dict(name='div', attrs={'id':'mainnews'})] + + feeds = [(u'Sve vijesti', u'http://www.vijesti.cg.yu/rss.php' )] + + def preprocess_html(self, soup): + soup.html['xml:lang'] = 'sr-Latn-ME' + soup.html['lang'] = 'sr-Latn-ME' + mtag = '<meta http-equiv="Content-Language" content="sr-Latn-ME"/>' + soup.head.insert(0,mtag) + return soup diff --git a/src/calibre/web/feeds/recipes/recipe_wash_post.py b/src/calibre/web/feeds/recipes/recipe_wash_post.py index bd4c78e333..58042d0d4a 100644 --- a/src/calibre/web/feeds/recipes/recipe_wash_post.py +++ b/src/calibre/web/feeds/recipes/recipe_wash_post.py @@ -9,6 +9,7 @@ class WashingtonPost(BasicNewsRecipe): __author__ = 'Kovid Goyal' use_embedded_content = False max_articles_per_feed = 20 + language = _('English') preprocess_regexps = [ (re.compile(i[0], re.IGNORECASE | re.DOTALL), i[1]) for i in diff --git a/src/calibre/web/feeds/recipes/recipe_wired.py b/src/calibre/web/feeds/recipes/recipe_wired.py index 7feb61bd9c..101adca7b0 100644 --- a/src/calibre/web/feeds/recipes/recipe_wired.py +++ b/src/calibre/web/feeds/recipes/recipe_wired.py @@ -12,6 +12,7 @@ class Wired(BasicNewsRecipe): __author__ = 'David Chen <SonyReader<at>DaveChen<dot>org>' description = 'Technology news' timefmt = ' [%Y%b%d %H%M]' + language = _('English') no_stylesheets = True #html2lrf_options = ['--base-font-size', '16'] diff --git a/src/calibre/web/feeds/recipes/recipe_wsj.py b/src/calibre/web/feeds/recipes/recipe_wsj.py index 46ac696ad1..a2d72abd99 100644 --- a/src/calibre/web/feeds/recipes/recipe_wsj.py +++ b/src/calibre/web/feeds/recipes/recipe_wsj.py @@ -13,13 +13,15 @@ class WallStreetJournal(BasicNewsRecipe): __author__ = 'Kovid Goyal' description = 'News and current affairs.' needs_subscription = True + language = _('English') max_articles_per_feed = 10 timefmt = ' [%a, %b %d, %Y]' - html2lrf_options = ['--ignore-tables'] + no_stylesheets = True remove_tags_before = dict(name='h1') remove_tags = [ dict(id=["articleTabs_tab_article", "articleTabs_tab_comments", "articleTabs_tab_interactive"]), {'class':['more_in', "insetContent", 'articleTools_bottom', 'aTools', "tooltip", "adSummary", "nav-inline"]}, + dict(rel='shortcut icon'), ] remove_tags_after = [dict(id="article_story_body"), {'class':"article story"},] @@ -34,6 +36,11 @@ class WallStreetJournal(BasicNewsRecipe): br.submit() return br + def postprocess_html(self, soup, first): + for tag in soup.findAll(name=['table', 'tr', 'td']): + tag.name = 'div' + return soup + def get_article_url(self, article): try: return article.feedburner_origlink.split('?')[0] @@ -43,8 +50,7 @@ class WallStreetJournal(BasicNewsRecipe): def cleanup(self): self.browser.open('http://online.wsj.com/logout?url=http://online.wsj.com') - def get_feeds(self): - return [ + feeds = [ #('Most Emailed - Day', 'http://online.wsj.com/xml/rss/3_7030.xml'), #('Most Emailed - Week', 'http://online.wsj.com/xml/rss/3_7253.xml'), #('Most Emailed - Month', 'http://online.wsj.com/xml/rss/3_7254.xml'), diff --git a/src/calibre/web/feeds/recipes/recipe_xkcd.py b/src/calibre/web/feeds/recipes/recipe_xkcd.py index 35a65ab948..36b776c380 100644 --- a/src/calibre/web/feeds/recipes/recipe_xkcd.py +++ b/src/calibre/web/feeds/recipes/recipe_xkcd.py @@ -12,6 +12,7 @@ class XkcdCom(BasicNewsRecipe): title = 'xkcd' description = 'A webcomic of romance and math humor.' __author__ = 'Martin Pitt' + language = _('English') use_embedded_content = False oldest_article = 60 keep_only_tags = [dict(id='middleContent')] diff --git a/src/calibre/web/feeds/recipes/recipe_zdnet.py b/src/calibre/web/feeds/recipes/recipe_zdnet.py index 6378f55ad8..2297427b50 100644 --- a/src/calibre/web/feeds/recipes/recipe_zdnet.py +++ b/src/calibre/web/feeds/recipes/recipe_zdnet.py @@ -14,6 +14,7 @@ class cdnet(BasicNewsRecipe): title = 'zdnet' description = 'zdnet security' __author__ = 'Oliver Niesner' + language = _('English') use_embedded_content = False timefmt = ' [%d %b %Y]' max_articles_per_feed = 40 diff --git a/src/calibre/web/feeds/recipes/recipe_zeitde.py b/src/calibre/web/feeds/recipes/recipe_zeitde.py index c37a487153..6e0f919d41 100644 --- a/src/calibre/web/feeds/recipes/recipe_zeitde.py +++ b/src/calibre/web/feeds/recipes/recipe_zeitde.py @@ -12,6 +12,7 @@ class ZeitDe(BasicNewsRecipe): title = 'Die Zeit Nachrichten' description = 'Die Zeit - Online Nachrichten' + language = _('German') __author__ = 'Kovid Goyal' use_embedded_content = False timefmt = ' [%d %b %Y]' diff --git a/src/calibre/web/fetch/simple.py b/src/calibre/web/fetch/simple.py index f5ffaf08b8..0d073ecce7 100644 --- a/src/calibre/web/fetch/simple.py +++ b/src/calibre/web/fetch/simple.py @@ -15,7 +15,7 @@ from PIL import Image from cStringIO import StringIO from calibre import setup_cli_handlers, browser, sanitize_file_name, \ - relpath, LoggingInterface + relpath, LoggingInterface, unicode_path from calibre.ebooks.BeautifulSoup import BeautifulSoup, Tag from calibre.ebooks.chardet import xml_to_unicode from calibre.utils.config import OptionParser @@ -53,7 +53,7 @@ def save_soup(soup, target): nm = ns.find('meta') metas = soup.findAll('meta', content=True) for meta in metas: - if 'charset' in meta['content']: + if 'charset' in meta.get('content', '').lower(): meta.replaceWith(nm) selfdir = os.path.dirname(target) @@ -62,7 +62,7 @@ def save_soup(soup, target): for key in ('src', 'href'): path = tag.get(key, None) if path and os.path.isfile(path) and os.path.exists(path) and os.path.isabs(path): - tag[key] = relpath(path, selfdir).replace(os.sep, '/') + tag[key] = unicode_path(relpath(path, selfdir).replace(os.sep, '/')) html = unicode(soup) with open(target, 'wb') as f: @@ -227,7 +227,7 @@ class RecursiveFetcher(object, LoggingInterface): return True def process_stylesheets(self, soup, baseurl): - diskpath = os.path.join(self.current_dir, 'stylesheets') + diskpath = unicode_path(os.path.join(self.current_dir, 'stylesheets')) if not os.path.exists(diskpath): os.mkdir(diskpath) for c, tag in enumerate(soup.findAll(lambda tag: tag.name.lower()in ['link', 'style'] and tag.has_key('type') and tag['type'].lower() == 'text/css')): @@ -280,7 +280,7 @@ class RecursiveFetcher(object, LoggingInterface): def process_images(self, soup, baseurl): - diskpath = os.path.join(self.current_dir, 'images') + diskpath = unicode_path(os.path.join(self.current_dir, 'images')) if not os.path.exists(diskpath): os.mkdir(diskpath) c = 0 diff --git a/src/cssutils/util.py b/src/cssutils/util.py index f2845de590..7b5b9b3857 100644 --- a/src/cssutils/util.py +++ b/src/cssutils/util.py @@ -840,7 +840,9 @@ def _readUrl(url, fetcher=None, overrideEncoding=None, parentEncoding=None): try: # encoding may still be wrong if encoding *is lying*! - if content is not None: + if isinstance(content, unicode): + decodedCssText = content + elif content is not None: decodedCssText = codecs.lookup("css")[1](content, encoding=encoding)[0] else: decodedCssText = None diff --git a/src/odf/odf2xhtml.py b/src/odf/odf2xhtml.py index 8a55fbd036..28ea9dc838 100644 --- a/src/odf/odf2xhtml.py +++ b/src/odf/odf2xhtml.py @@ -77,6 +77,8 @@ class StyleToCSS: (FONS,u"border-left"): self.c_fo, (FONS,u"border-right"): self.c_fo, (FONS,u"border-top"): self.c_fo, + (FONS,u"break-after"): self.c_break, + (FONS,u"break-before"): self.c_break, (FONS,u"color"): self.c_fo, (FONS,u"font-family"): self.c_fo, (FONS,u"font-size"): self.c_fo, @@ -139,6 +141,13 @@ class StyleToCSS: selector = rule[1] sdict[selector] = val + def c_break(self, ruleset, sdict, rule, val): + property = 'page-' + rule[1] + values = {'auto': 'auto', 'column': 'always', 'page': 'always', + 'even-page': 'left', 'odd-page': 'right', + 'inherit': 'inherit'} + sdict[property] = values.get(val, 'auto') + def c_border_model(self, ruleset, sdict, rule, val): """ Convert to CSS2 border model """ if val == 'collapsing': @@ -1169,6 +1178,9 @@ class ODF2XHTML(handler.ContentHandler): if specialtag is None: specialtag = 'p' self.writedata() + if not self.data: + # Give substance to empty paragraphs, as rendered by OOo + self.writeout(' ') self.closetag(specialtag) self.purgedata() diff --git a/upload.py b/upload.py index fb88efc149..66a4a62e30 100644 --- a/upload.py +++ b/upload.py @@ -77,7 +77,7 @@ def run_windows_install_jammer(installer): def build_windows(shutdown=True): installer = installer_name('exe') - vm = '/vmware/Windows XP/Windows XP Professional.vmx' + vm = '/mnt/backup/calibre_windows_xp_home/calibre_windows_xp_home.vmx' start_vm(vm, 'windows', BUILD_SCRIPT%('python setup.py develop', 'python','installer\\\\windows\\\\freeze.py')) if os.path.exists('build/py2exe'): shutil.rmtree('build/py2exe')